элементы, доступные для редактирования и не являющиеся кнопочными
-
18-09-2019 - |
Вопрос
Я могу легко выполнить execcommand для выбора contenteditable, если использую кнопку.Однако использование любого другого элемента завершается неудачей.
Почему это происходит и как я могу заставить это работать, используя элемент div.
Спасибо.
Решение
Вы могли бы сохранить выделение, используя mousedown
событие на элемент, используемый вместо кнопки, и восстановить его снова после фокусировки редактируемого элемента в click
событие.
Я изменил пример кода: http://jsbin.com/atike/40/edit.Вот код:
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
var ranges = [];
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
ranges.push(sel.getRangeAt(i));
}
return ranges;
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(savedSel) {
if (savedSel) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
for (var i = 0, len = savedSel.length; i < len; ++i) {
sel.addRange(savedSel[i]);
}
} else if (document.selection && savedSel.select) {
savedSel.select();
}
}
}
$(function() {
var savedSel;
$('.bold').mousedown(function () {
savedSel = saveSelection();
});
$('.bold').click(function () {
$('#hello').focus();
if (savedSel) {
restoreSelection(savedSel);
}
document.execCommand("bold", false, null);
});
});
Другие советы
Большинство, если не все, существующих редакторов WYSIWYG используют iframe
элемент для того, чтобы не потерять выделение.Другой подход, хотя я его и не пробовал, заключался бы в сохранении каждого выбора, сделанного на этой странице после mouseup
триггеры событий.
Взгляните на эту страницу о Мидас, Встроенный форматированный текстовый редактор Gecko.
Что происходит, так это то, что когда вы нажимаете на текстовый узел, браузер хочет выделить этот текст.Кнопки не являются частью текстового потока и поэтому не вызовут нового выделения.
Все, что вам нужно сделать, это запретить браузеру выполнять повторный выбор.Когда в click
событие, которое вы в данный момент наблюдаете, запускает выделение, которое уже произошло, и действовать слишком поздно.Действие начинает происходить на mousedown
для всех браузеров ожидайте MSIE, в котором есть специальный выбор событий.
Это работает для меня во всех браузерах:
jQuery('.bold')
.attr('unselectable','on') // prevents selection in MSIE
.bind('mousedown',function (e) {
document.execCommand("bold", false, null);
e.preventDefault(); // prevents selection in all but MSIE
});
Есть несколько сложностей с использованием событий выбора MSIE (например, также необходимо блокировать перетаскивание), поэтому проще просто отключить возможность выбора элемента, который вы используете в качестве кнопки со специализированным атрибутом unselectable
(требуется значение "вкл.").
Очевидно, что вы все еще можете выполнить execCommand
обработка в click
события и просто запустите код предотвращения выбора для всех элементов, предназначенных в качестве "кнопок":
jQuery('.buttonlike')
.attr('unselectable','on') // prevents selection in MSIE
.bind('mousedown',function (e) {
e.preventDefault(); // prevents selection in all but MSIE
});
jQuery('#edit-bold').click(function(){
document.execCommand("bold", false, null);
});
Приятноправить использует комбинацию методов.
Большинство элементов панели инструментов имеют установленный атрибут "невыбираемый" - это работает для Internet Explorer.
Для тех же элементов он регистрируется для события "наведение курсора мыши" и переопределяет действие по умолчанию - это предотвращает как текстовое решение, так и фокусировку.Это предназначено только для браузеров, отличных от IE.
Некоторые элементы панели инструментов должны иметь возможность фокусироваться на тексте и выделять его, например поле для вставки ссылки или изображения.Для этого он сохраняет выделенное изображение до того, как редактор потеряет фокус, а затем восстанавливает его после того, как пользователь закончит редактирование и потребуется внести изменения.
О том, как это реализовать, ознакомьтесь с кодом NicEdit.Поиск названий функций:
- Гетсель
- Получение
- Выбор
- Сохранение
- Реставратор
...
При этом используется функция getSelection браузера() или document.selection для получения выделения, функция getRangeAt() для преобразования его в диапазон и функция AddRange() или select() для восстановления этого диапазона в виде выделения.