Удалить прямой родительский узел выделения (<b>) - PullRequest
0 голосов
/ 17 мая 2018

Я хотел бы удалить и добавить тег <b> к выделенному тексту, просто щелкнув по нему.

Я уже могу заключить выделенный текст в тег <b> с помощью:

if (window.getSelection) 
{
    selection = getSelection();

    var newNode = document.createElement("b");
    range.surroundContents(newNode);        
}

Теперь, когда я хотел бы иметь метод удаления тега <b>, который я добавил ранее,но обычно показанный метод использования range.commonAncestorContainer дал бы мне самого низкого родителя типа <div>.

В рамках отладки я просто изменил код, который использовал для добавления тега <b> (чтобы сделатьконечно, у меня был тег, я также сначала добавил его) для удаления родительского узла.

if (window.getSelection) {
    selection = getSelection();

    var newNode = document.createElement("b");
    range.surroundContents(newNode);
    node = range.commonAncestorContainer;
    node.remove();
}

Это удалит родительский элемент <div> недавно добавленного тега <b> вместо только <b> сам тег.

Для справки, вот HTML:

<div contenteditable="true" id="input" class="inputblock" onclick="getClick()" onkeypress="changeNodeType(event)" data-text="Please paste your text here."></div>

Тег <b> будет создан в тексте, вставленном в показанный <div>.

Тот факт, что он также удаляет контент, можно игнорировать.Я найду способ поработать с этим.

1 Ответ

0 голосов
/ 17 мая 2018

У меня, к сожалению, не так много времени, как я бы хотел потратить, чтобы написать решение с полным кодом, но вот как я решил это в прошлом:

  1. Нормализацияваш ассортиментЭто самая сложная часть.IE, edge и разные браузеры ведут себя по-разному, поэтому вам придется обрабатывать множество особых крайних случаев.Например, если диапазон находится прямо перед пустым текстовым узлом, IE будет делать странные вещи
  2. . Для вашего начального и конечного контейнера, если они являются текстовыми узлами, ничего не делать
  3. В противном случае вам необходимоиспользуйте NodeIterator, чтобы выполнить обход в порядке и перейти к следующему узлу для начального контейнера и предыдущему узлу для конечного контейнера.Это решает случай, когда при выборе чего-то вроде <b>hello</b> выбор может быть либо |<b>hello</b>|, либо <b>|hello|</b>.Нормализуя и спускаясь по дереву, вы получите - в основном эквивалентный - выбор <b>|hello|</b> в обоих случаях.Трудно объяснить это без рисунков, поэтому я бы посоветовал вам нарисовать дерево DOM и перейти к следующему внутреннему дочернему элементу начального контейнера и предыдущему внутреннему дочернему элементу конечного контейнера.
  4. Как только вы уложились вниз, вы можете начать идти вверх по дереву, чтобы найти жирный тег.Это просто node.contains('b');
  5. Сделайте это как для начального, так и для конечного узла, затем посмотрите, не указываете ли вы на один и тот же жирный тег, и текстовое содержимое совпадает с вашим выделением.
  6. Если это так, вы нашли свой жирный тег в nuke.

Это нетривиальный объем кода, и он требует кучу тестов, потому что это действительно шаткокрайние случаи с настройкой выделения и диапазона в браузерах.Я долго боролся с соперниками :-) и желаю удачи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...