Выключить произвольный сброс курсора в WYSIWYG
У меня есть ситуация, связанная с KnockoutJS и плагином jwysiwyg ( https://github.com/jwysiwyg/jwysiwyg). Я использую пользовательскую привязку, показанную ниже. Однако всякий раз, когда пользователь обновляет текст во второй строке, обновление содержимого через привязку приводит к сбросу курсора в самое начало редактора. Таким образом, всякий раз, когда пользователь приостанавливает набор текста более чем на 1 секунду после обновления, он вынужден щелкнуть туда, где он был до того, как продолжить.
ko.bindingHandlers.wysiwyg = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().wysiwygOptions || {};
var value = ko.utils.unwrapObservable(valueAccessor());
var $e = $(element);
$.extend(true, {
initialContent : value
}, options);
$e.wysiwyg(options);
//handle the field changing
function detectFn() {
var observable = valueAccessor();
var newvalue = $e.wysiwyg("getContent");
observable(newvalue);
}
var current = $e.wysiwyg('document');
var timer;
current.bind({
keyup: function(){
clearTimeout(timer);
timer = setTimeout(detectFn, 1000);
}
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$e.wysiwyg('destroy');
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).wysiwyg("setContent", value);
ko.bindingHandlers.value.update(element, valueAccessor);
}
};
(Привязка затем используется этим)
<textarea data-bind="wysiwyg: yourViewModelValue"></textarea>
Как я могу получить позицию каретки для восстановления курсора после завершения обновления? Или какие другие решения существуют, чтобы курсор не двигался при обновлении?
РЕДАКТИРОВАТЬ: JSFiddle, чтобы продемонстрировать проблему. http://jsfiddle.net/797ZL/ Обратите внимание, что происходит, когда вы печатаете во второй строке или за ее пределами, затем делаете паузу на секунду, вызывая сброс курсора.
1 ответ
Вот что вы видите:
- Пользователь вводит текст в редактор WYSIWYG
- Пользователь перестает печатать, и время ожидания истекает через 1 секунду, вызывая обнаружение Fn
- DetectiveFn получает новое значение из редактора WYSIWYG и обновляет ваш наблюдаемый
- Ваша наблюдаемая, будучи обновленной, запускает метод обновления на вашем пользовательском связывателе
- Метод обновления в пользовательском связывателе получает значение из наблюдаемой и устанавливает его в редакторе WYSIWYG
- Редактор WYSIWYG, для которого установлено новое значение, перемещает курсор в верхнюю строку
Это можно исправить, остановив действия в середине шага 5 и обновив значение в редакторе WYSIWYG только в том случае, если оно отличается от значения в наблюдаемой - то есть, если наблюдаемое было обновлено из-за пределов редактора WYSIWYG.
Измените свой метод обновления на это:
update: function (element, valueAccessor) {
var newValue = ko.utils.unwrapObservable(valueAccessor());
var oldValue = $(element).wysiwyg("getContent");
if (newValue !== oldValue) {
$(element).wysiwyg("setContent", newValue);
}
// ko.bindingHandlers.value.update(element, valueAccessor);
}
Я закомментировал последнюю строку этого метода... он кажется посторонним, и я не совсем уверен, почему он там есть.
Кроме того, эти строки кода, похоже, тоже ничего не делают:
$.extend(true, {
initialContent : value
}, options);
Я думаю, что вы пытаетесь сделать, это добавить свойство initialContent к объекту параметров. Это можно сделать следующим образом:
$.extend(options, {initialContent: value});
Однако даже в этом нет необходимости, поскольку метод обновления вызывается после метода init, а значение из наблюдаемого загружается в редактор WYSIWYG в это время.
Вот скрипка с обновленным кодом: http://jsfiddle.net/tlarson/797ZL/2/