Update/remove text that is spread to different nod

2019-07-17 04:00发布

The title may not seem that self-explanatory, but the question is actually pretty simple. Imagine the following code:

<div class="line">
    Some text node here. <span>Some nodeType 3 here.</span> 
    More text here. <span>And here as well.</span>
</div>

Now, using javascript I'd like to delete the contents of the div. So something like:

function deleteContent(from, to) { 
    // Some code to execute here
}

and the result will be something like:

<div class="line">
    Some text node here. <span>Some nodeType</span>
</div>

So basically, in theory, it's like using the slice function div.innerHTML.slice(from, to) except that this would only work if there were no tags within the div. I've already thought about creating a text range and deleting the contents with deleteContent but I don't know if it is the simplest way to go. What are your suggestions?

PS: I'd like to have a code that is neat and logical.

EDIT

As a response to Felix: Yes, I treat from and to as two integers. And for whitespaces, in my application I'll have to understand each whitespace seperately. That is, &nbsp;&nbsp; are two characters.

标签: javascript
1条回答
Juvenile、少年°
2楼-- · 2019-07-17 04:14

I'm working on exactly this for my Rangy library and I'm almost ready to release it. In the meantime, you can use something like the following that will work in most situations but has drawbacks:

  • doesn't work in IE < 9
  • doesn't take into account implicit line breaks from block elements and <br>s
  • doesn't ignore invisible text, such as contents of <script> and <style> element or text inside elements with CSS display set to none
  • doesn't collapse spaces as they would appear on the rendered page
  • other subtleties

Live demo: http://jsfiddle.net/nT28h/

Code:

function createRangeFromCharacterIndices(containerEl, start, end) {
    var charIndex = 0, range = document.createRange(), foundStart = false, stop = {};
    range.setStart(containerEl, 0);
    range.collapse(true);

    function traverseTextNodes(node) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && start >= charIndex && start <= nextCharIndex) {
                range.setStart(node, start - charIndex);
                foundStart = true;
            }
            if (foundStart && end >= charIndex && end <= nextCharIndex) {
                range.setEnd(node, end - charIndex);
                throw stop;
            }
            charIndex = nextCharIndex;
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i]);
            }
        }
    }

    try {
        traverseTextNodes(containerEl);
    } catch (ex) {
        if (ex == stop) {
            return range;
        } else {
            throw ex;
        }
    }
}

function deleteBetweenCharacterIndices(el, from, to) {
    var range = createRangeFromCharacterIndices(el, from, to);
    range.deleteContents();
}
查看更多
登录 后发表回答