Палитра цветов радужной оболочки с расширенной библиотекой - сохранение выделения текста

Я использую Iris Colourpicker (http://automattic.github.io/Iris/) в моем богатый редактор HTML, позволяющий пользователям обновлять цвет текста в содержательном абзаце.

Проблема в том, что после вызова первого события «изменение» я теряю выделение, и, следовательно, никакие последующие изменения цвета не применяются.

Я попытался использовать замечательную Rangy библиотеку Тима Дауна, чтобы сохранить выделение и восстановить его, когда событие изменения уволен. Это работает в первый раз, когда событие вызывается, но каждый раз после этого не работает.

У меня есть эта функция, чтобы сохранить выбор до открытия палитры цветов

// Saves current selection.  Colour picker widget is displayed after this is called.
jQuery(".tve_save_selection").on("mousedown", function(e) {
        window.textselection = rangy.saveSelection();
});

И вот как инициализируется палитра цветов Iris:

var text_colourpicker_options = {
    change: function (event, ui) {
        color = ui.color.toString();
        rangy.restoreSelection(window.textselection);
        var sel = rangy.getSelection();
        if (sel.toString().length) {
         document.execCommand('ForeColor', false, color);
        }
    },
    hide: true,
    palettes: window.tve_custom_colours,
};

Похоже, что для палитры цветов нет события «закрытия», поэтому я не могу применить execCommand после того, как пользователь выбрал цвет.

Я думаю, что мне может потребоваться сгенерировать новый диапазон после срабатывания функции document.execCommand (), но поскольку DOM изменился, я не знаю, как определить новый диапазон выбора.

Любая помощь по этому поводу будет очень признательна!


person Paul McCarthy    schedule 18.01.2014    source источник


Ответы (1)


Судя по приведенному вами описанию, я делаю вывод, что анонимная функция, которой присвоена опция change, вызывается каждый раз, когда пользователь меняет цвет. В этом случае ваш код не может работать.

Почему не работает

Это не может работать, потому что ваш код вызывает rangy.restoreSelection несколько раз с одним и тем же сохраненным выделением, тогда как эту функцию можно вызвать только один раз с сохраненным выделением. В этом можно убедиться из документации. :

Восстанавливает выделение из объекта, ранее возвращенного rangy.saveSelection (). Он удаляет все скрытые элементы маркера, созданные этим методом.

(Курсив добавлен.) Маркеры - это то, что позволяет методам сохранения и восстановления работать, поэтому, если они удалены, последующие вызовы не могут работать. В этом также можно убедиться, посмотрев на код restoreSelection, сокращенный здесь до того, что имеет отношение к этому вопросу:

function restoreSelection(savedSelection, preserveDirection) {
    if (!savedSelection.restored) {
        // ...
        // Actual work
        // ...
        savedSelection.restored = true;
    }
}

При первом вызове savedSelection.restored будет ложным, и будет выполнена фактическая работа по восстановлению выбора. При последующих вызовах того же выбора savedSelection.restored будет истинным, и никакая работа выполняться не будет.

Решение

После восстановления снова сохраните выделение:

rangy.restoreSelection(window.textselection);
window.textselection = rangy.saveSelection();
person Louis    schedule 20.01.2014
comment
Спасибо, Луи, я реализовал то, что вы предложили, и это действительно очень хорошо работает! - person Paul McCarthy; 21.01.2014