Используйте JavaScript для расширения Диапазона DOM для покрытия частично выбранных узлов

Я работаю над визуальным редактором как веб-приложение, в основном XML-редактор, записанный в JavaScript.

Мой код JavaScript должен перенести выбор узлов от contentEditable контейнера отделения. Я использую методы, описанные в MDC. Но так как я должен синхронизировать содержание контейнеров отделения со своим XML DOM, я хотел бы избежать частичных выборов, как описано в диапазонах w3c:

Title

Blah xyz.

............^----------------^............

Этот выбор запускает внутреннего H1 и заканчивается в P, я хотел бы, чтобы он включал H1, P полностью.

Существует ли простой способ расширить выбор для покрытия частично выбранных детей полностью? В основном я хочу использовать range.surroundContents (), не сталкиваясь с исключением.

(Код не должен работать с оперой/IE),

11
задан ko-dos 19 March 2010 в 13:22
поделиться

3 ответа

Глядя на документацию MDC, я могу сделать что-то вроде этого:

Selection.prototype.coverAll = function() {
    var ranges = [];
    for(var i=0; i<this.rangeCount; i++) {
        var range = this.getRangeAt(i);
        while(range.startContainer.nodeType == 3
              || range.startContainer.childNodes.length == 1)
            range.setStartBefore(range.startContainer);
        while(range.endContainer.nodeType == 3
              || range.endContainer.childNodes.length == 1)
            range.setEndAfter(range.endContainer);
        ranges.push(range);
    }
    this.removeAllRanges();
    for(var i=0; i<ranges.length; i++) {
        this.addRange(ranges[i]);
    }
    return;
};

Вы можете попробовать это здесь: http://jsfiddle.net/GFuX6/9/

edit: Обновлено, чтобы браузер корректно отображал расширенный выбор. Это делает то, что вы просили, даже если выделение содержит несколько диапазонов (с Ctrl).

Чтобы сделать несколько частичных узлов Bold, вот решение:

Selection.prototype.boldinize = function() {
    this.coverAll();
    for(var i=0; i<this.rangeCount; i++) {
        var range = this.getRangeAt(i);
        var parent = range.commonAncestorContainer;
        var b = document.createElement('b');
        if(parent.nodeType == 3) {
            range.surroundContents(b);
        } else {
            var content = range.extractContents();
            b.appendChild(content);
            range.insertNode(b);
        }
    }
};
9
ответ дан 3 December 2019 в 10:25
поделиться

Если вы имеете в виду, что хотите включить теги H1 и P (т.е. допустимую разметку), не беспокойтесь. Вы получаете это бесплатно. Если вы имеете в виду, что хотите, чтобы он включал все содержимое в (частичный) выбор, вам необходимо получить доступ к объекту Selection. Прочтите об этом в Введение Quirksmode в Range .

0
ответ дан 3 December 2019 в 10:25
поделиться

Благодаря Alsciende я наконец придумал код на http://jsfiddle.net/wesUV/21/ . Этот метод не такой жадный, как другой. После функции coverAll () функция SurroundContents () всегда должна работать.

Selection.prototype.coverAll = function() {
  var ranges = [];   
  for(var i=0; i<this.rangeCount; i++) {
    var range = this.getRangeAt(i);
    var ancestor = range.commonAncestorContainer;
    if (ancestor.nodeType == 1) {            
        if (range.startContainer.parentNode != ancestor && this.containsNode(range.startContainer.parentNode, true)) {
            range.setStartBefore(range.startContainer.parentNode);
        }
        if (range.endContainer.parentNode != ancestor && this.containsNode(range.endContainer.parentNode, true)) {
                range.setEndAfter(range.endContainer.parentNode);
        }
    }
    ranges.push(range);
  }
  this.removeAllRanges();
  for(var i=0; i<ranges.length; i++) {
    this.addRange(ranges[i]);
  }
  return;
};

И функция жирного шрифта:

Selection.prototype.boldinize = function() {
  for(var i=0; i<this.rangeCount; i++) {        
    var range = this.getRangeAt(i);
    var b = document.createElement('b');
    try {
        range.surroundContents(b);
    } catch (e) {
        alert(e);
    }
  }
};
0
ответ дан 3 December 2019 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: