Требовать
1. При входе @, появляется подходящее меню друга
2. Когда курсор входит в тег, содержащий «@friends», в меню появится меню
3. При нажатии на Backspace, чтобы удалить, если курсор находится перед тем, что на передней части тега, содержащего «@Friends», появится меню.
4. Совместим с т.е. Firefox.
Конкретные практики
Для требований 1 естественно думать о связывании событий с входным ящиком. Здесь вам нужно связать Муседаун, а не MouseUp. Потому что, если это MouseUp, использование event.preventDefault () не может помешать клавиатуре войти @. Кроме того, использование возврата false в обратном вызове событий здесь не будет работать.
После привязки события Mousedown вам нужно вставить пользовательский тег, содержащий «@Friends». Входная коробка на Sina Weibo сделана с Textarea. Я не могу знать, как это обрабатывается внутри, поэтому я должен читать Baidu Tieba.
Вы можете видеть, что тег <span class = 'at'> </span> был вставлен в почтовый план. Это должно быть удобно для сопоставления фона с регулярными выражениями.
Специфический
Кода -копия выглядит следующим образом:
vm.check_key = function (e) {
var Editor = $ ('Editor'), Range;
if (e.shiftkey && e.keycode == 50) {
if (document.selection && document.selection.createrange) {
range = document.selection.createrange ();
range.pastehtml ("<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}еще{
document.execcommand ("inserthtml", false "<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}
e.preventdefault ();
}
};
Это требует введения в курсор, поэтому используется диапазон.
Затем отображается меню, ключ - как его позиционировать. Мой подход очень мусор, который должен добавить идентификатор в вставленную пролету, а затем найти меню в соответствии с положением идентификатора пролета. Если есть лучший способ, пожалуйста, дайте мне знать.
Специфический
Кода -копия выглядит следующим образом:
функция at_box_show (at) {
var at_pos = avalon ($ (at)). position ();
$ ('at_box'). style.left = at_pos.left+'px';
$ ('at_box'). style.top = at_pos.top+16+'px';
$ ('at_box'). style.display = 'block';
}
var at_index = 0, cur_index = 0;
avalon.define ('editor', function (vm) {
vm.item_click = function () {
$ ('at'+cur_index) .innerhtml = "@"+this.innerhtml;
$ ('at_box'). style.display = 'none';
at_index ++;
};
vm.check_key = function (e) {
var Editor = $ ('Editor'), a = getCharacterPrecedingCaret (редактор), диапазон;
if (e.shiftkey && e.keycode == 50) {
if (document.selection && document.selection.createrange) {
range = document.selection.createrange ();
range.pastehtml ("<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}еще{
document.execcommand ("inserthtml", false "<span id = 'at"+at_index+"' class = 'at_span'>@</span>");
}
at_box_show ('at'+at_index);
cur_index = at_index;
e.preventdefault ();
}
};
});
AT_SHOW_BOX находит AT_BOX в соответствии с недавно вставленным идентификатором SPAN, а затем отображает меню. cur_index представляет идентификатор SPAN, где в настоящее время находится курсор. Установите эту переменную, потому что пользователь может перематывать и изменить вставленную пролету, и AT_INDEX постоянно увеличивается, поэтому здесь также необходима переменная.
Пользователь нажимает на элемент друга в меню, чтобы запустить обратный вызов item_click. В обратном вызове добавьте имя друга в текущий промежуток, используя Inserhtml. Затем скрыть меню, at_index ++.
Выше приведено слушание Shift+@, затем прослушивание удаления обратного пространства.
Кода -копия выглядит следующим образом:
Функция getTextBeForeCursor (Containerel) {
var предшествующий charChr = "", sel, range, precedingrange;
if (window.getSelection) {
sel = window.getSelection ();
if (sel.rangecount> 0) {
range = sel.getrangeat (0) .clonerange ();
range.collapse (true);
range.setStart (контейнель, 0);
precedchar = range.clonecontents ();
}
} else if ((sel = document.selection)) {
range = sel.createrange ();
предыдущий диапазон = range.duplicate ();
предшествующий
precedingrange.setendpoint ("endtostart", range);
предыдущий char = предшествующий
}
возврат предыдущий штам;
}
Функция getTextBeforeCursor заключается в том, чтобы получить контент перед курсором. В связи с совместимостью эта функция может получить документы, который является всем контентом перед курсором в стандартном браузере, и в IE вы можете получить только текст (не узел). Однако эта строка HTML может быть преобразована в DocumentFragment. В Avalon Parsehtml может использоваться для превращения строки HTML в узел. Вы также можете получить узел, используя $ (html) [0] в jQuery.
С помощью этой функции вы можете использовать LastChild, чтобы определить, находится ли курсор в LastChild в HTML перед курсором, и эта последняя часть является пролетом.
Специфический
Кода -копия выглядит следующим образом:
var a = getTextBeforeCursor ($ ('editor'));
if (e.keycode == 8) {
if (!-[1,]) {
var b = avalon.parsehtml (a) .lastchild;
}еще{
var b = a.lastchild;
}
if (b.nodeType == 1 && b.nodeName == 'span') {
var id = b.id;
cur_index = b.id.substring (2);
at_box_show (b.id);
}еще
$ ('at_box'). style.display = 'none';
}
Наконец, курсор входит в этикетку SPAN и отображает меню. Это, очевидно, требует связывания события мыши. MouseUp здесь связан, потому что, если Mousedown связан, вам нужно снова щелкнуть мышью на метке Span, прежде чем меню может быть отображено. Что касается принципа, он похож на вышесказанное.
Кода -копия выглядит следующим образом:
vm.check_mouse = function (e) {
var Editor = $ ('Editor'), a = getTextBeforeCursor (редактор);
if (!-[1,]) {
var b = avalon.parsehtml (getTextBeforeCursor (редактор)). LastChild;
}еще{
var b = a.lastchild;
}
if (b! = null && b.nodetype == 1 && b.nodename == 'span') {
var id = b.id;
cur_index = b.id.substring (2);
at_box_show (b.id);
}еще
$ ('at_box'). style.display = 'none';
};
Обратите внимание, что если курсор находится в диапазоне, он должен быть удален, и AT_BOX должен быть расположен в соответствии с этим идентификатором, а также сброшен CUR_INDEX.
Что касается меню обновления Ajax, я не буду делать сопоставление персонажа
Эффект
Firefox
IE8
IE7
IE6
скачать
Выше всего, все контент, описанный в этой статье. Я надеюсь, что для всех будет полезно понять JavaScript.