0

So I have this code below that I use to parse html strings into an iframe (richTextField). The code working properly and has been found on the first answer by Tim Down. I don't fully understand it. Especially the part with range.

From a doc here:

The Range interface represents a fragment of a document that can contain nodes and parts of text nodes.

I'm assuming the range object will then be the selection of the user including the tags like <div> if selected.

I changed a bit the code of Tim to this JSFiddle and I'm having trouble understanding why my 2 divs are placed within each other, (or even the code in general).

So here is the code with my wrong understanding on the side , I would appreciate if someone could correct me:

var html = "<br/>"  +  "<div style='background:grey;'>1<div/>"+
        "<div style='border:2px solid red'>2</div><br/>";
var window = richTextField;
var sel, range;
document.getElementById('richTextField').focus();
if (window.getSelection) {
    // IE9 and non-IE
    sel = window.getSelection(); // 1. So here I get it, we get what the cursor selected.
    if (sel.getRangeAt && sel.rangeCount) { // 2. This I don't understand even after reading the doc (there are no return type in the doc which makes it hard to understand).
        range = sel.getRangeAt(0); // 2.1 First position in the selection ?
        range.deleteContents();    // 3. I'm assuming we delete the highlighted area by the user.

        var el = richTextField.document.createElement("div");   4. // So we create a div that we put in the doc tree of the iframe (richtextField).
        el.innerHTML = html;  5. // some text in that div, here my text contains another div.
        var frag = richTextField.document.createDocumentFragment(), node, lastNode;  6. // I'm usually programming in java and this syntax is unknown to me. 
         // what are those after the "," comas ?
         //createDocumentFragment as the doc says creates a fragment but doesn't push it to the DOM 

        while ((node = el.firstChild)) {  7. // I'm assuming we go through all the childs of the root of the el node (which itself is the div we created on number 4.
            lastNode = frag.appendChild(node);  /// we append every node to the fragment created on 7. The fragment is not  yet pushed to the dom tree.
        }
        range.insertNode(frag);  //8. Hum here we push the fragment in the dom. But wasn't that what we did already in 4 ?

        // Preserve the selection
        if (lastNode) {
            range = range.cloneRange();
            range.setStartAfter(lastNode);
            range.collapse(true);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
Community
  • 1
  • 1
Ced
  • 15,847
  • 14
  • 87
  • 146
  • 2
    Typo `
    ` should be `` [http://jsfiddle.net/jwvwwv9j/2/](http://jsfiddle.net/jwvwwv9j/2/)
    – joyBlanks Sep 10 '15 at 19:36
  • @joyBlanks lmao thanks. I actually made the same typo over and over again because I tested many time with different tags. It's amazing how the brain can trick you. Been 2 hours. Anyway my question is still interesting beside the typo I think. – Ced Sep 10 '15 at 19:39

1 Answers1

3

A Range boundary is not a character offset within a string representation of HTML. Rather, it is an offset within a DOM node. If the node is a text node, for example, the boundary is expressed as a character offset within the node's text. If the node is an element, it is expressed as the number of child nodes of the node prior to the boundary. For example, in the following HTML, with a Range whose boundaries are denoted by |:

<div id="test">foo|bar<br>|<br></div>

... the range's start boundary lies at offset 3 in the text node that is the first child of the element, while the end boundary lies at offset 2 within the , since there are two child nodes (text node "foobar" and one
element) lying before the boundary. You would create the range programmatically as follows:

var range = rangy.createRange(); // document.createRange() if not using Rangy
var div = document.getElementById("test");
range.setStart(div.firstChild, 3);
range.setEnd(div, 2);

Reference: How do I create a range object when I know just the character offsets?

Community
  • 1
  • 1
joyBlanks
  • 6,419
  • 1
  • 22
  • 47