Выключить произвольный сброс курсора в 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 ответ

Решение

Вот что вы видите:

  1. Пользователь вводит текст в редактор WYSIWYG
  2. Пользователь перестает печатать, и время ожидания истекает через 1 секунду, вызывая обнаружение Fn
  3. DetectiveFn получает новое значение из редактора WYSIWYG и обновляет ваш наблюдаемый
  4. Ваша наблюдаемая, будучи обновленной, запускает метод обновления на вашем пользовательском связывателе
  5. Метод обновления в пользовательском связывателе получает значение из наблюдаемой и устанавливает его в редакторе WYSIWYG
  6. Редактор 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/

Другие вопросы по тегам