Замена спорных персонажей на лету с (или без) ранги - PullRequest
0 голосов
/ 20 февраля 2012

Я работаю над небольшим экспериментальным редактором, где я хотел бы визуализировать время между напечатанными символами.Поэтому я использую javascript и contenteditable div, чтобы обернуть каждый символ SPAN и атрибутом timestamp.Я создаю небольшую функцию с помощью rangy :

function insertAtCursor(char, timestamp) { 
    var sel = rangy.getSelection();
    var range = sel.rangeCount ? sel.getRangeAt(0) : null;
    if (range) {
        var el = document.createElement("span");
        $(el).attr('time', timestamp); 
        el.appendChild(document.createTextNode(char)); 
        range.insertNode(el); 
        range.setStartAfter(el);
        rangy.getSelection().setSingleRange(range); 
    } 
}

Теперь я столкнулся с двумя проблемами с этой концепцией, где я был бы признателен за некоторую помощь:

a,С помощью вышеуказанной функции вывод заканчивается во вложенном диапазоне, как показано здесь:

<span time="12345">a
  <span time="12345">b
    <span time="12345">c</span>
  </span>
</span>

b.Даже если бы я мог запустить вышеупомянутую функцию, действие копирования и вставки или перетаскивания, возможно, также закончилось бы каким-нибудь вложенным диапазоном ... и мне интересно, есть ли способ вообще избежать этого?

Спасибо, Андреас

1 Ответ

2 голосов
/ 20 февраля 2012

Я не уверен, что это хорошая идея в целом, особенно если текст может стать большим. Пара улучшений:

  • time должно быть data-time для проверки как HTML5
  • вам нужно обработать случай, когда какой-то контент выбран (добавление range.deleteContents() подойдет).

Однако, если вы собираетесь это сделать, я бы предложил проверить, находится ли курсор в конце текстового узла внутри существующего <span>, и добавить новый <span> после родительского узла текстового узла. Примерно так:

Демонстрация в реальном времени: http://jsfiddle.net/kWL82/1/

Код:

function insertAtCursor(char, timestamp) { 
    var sel = rangy.getSelection();
    var range = sel.rangeCount ? sel.getRangeAt(0) : null;
    var parent;
    if (range) {
        var el = document.createElement("span");
        $(el).attr('data-time', timestamp); 
        el.appendChild(document.createTextNode(char));

        // Check if the cursor is at the end of the text in an existing span
        if (range.endContainer.nodeType == 3
                && (parent = range.endContainer.parentNode)
                && (parent.tagName == "SPAN")) {
            range.setStartAfter(parent);
        }

        range.insertNode(el); 
        range.setStartAfter(el);
        rangy.getSelection().setSingleRange(range); 
    } 
}
...