0

In a contentEditable-DIV I try to get the HTML-Code from strat-Position 0 to end-position where the user has clicked.

<div id="MyEditableId" contentEditable="true">
  1. Some text 123. <span style="background-color: #0CF;">text 123</span> 456 <span style="background-color: #9F3;">2-> abc </span>
    <br />
    <p> E.g. here is clicked: "click" Text after click </p>
    <p></p>
    <br />
    end of text.
</div>

Something as below code snippet, which delivers the text from 0 to end of clicked node. But I need also the HTML-Code in contentEditable-DIV.

$('#MyEditableId').on('mouseup', function(event) {
    var MyEditable = document.getElementById('MyEditableId');
    MyEditable.focus();
    range = document.createRange();

    // endOffset: It will be better the length of where actually was clicked, e.g. after 15-characters. But this.length will be also ok.
    endOffset = $(this).length;
    range.setStart(MyEditable.firstChild,0);
    range.setEnd(event.target,endOffset);
    var selection = window.getSelection();
    selection.addRange(range);

    // Below I get the selected text from 0 to end of clicked node. But I need the selected HTML-Code from 0 to end of clicked position.
    alert( window.getSelection() );
});

I expect for the result something as follows:

 1. Some text 123. <span style="background-color: #0CF;">text 123</span> 456 <span style="background-color: #9F3;">2-> abc </span>
    <br />
    <p> E.g. here is clicked: "click"

How can I get the HTML-Code instead of text in my contentEditable-DIV? Thanks In Advance.

user3815508
  • 369
  • 4
  • 20

3 Answers3

1

You can select the div and use its property innerHTML

http://jsfiddle.net/at917rss/

<div id="MyEditableId" contentEditable="true">
  1. Some text 123. <span style="background-color: #0CF;">text 123</span> 456 <span style="background-color: #9F3;">2-> abc </span>
    <br />
    <p> E.g. here is clicked: "click" Text after click </p>
    <p></p>
    <br />
    end of text.
</div>

    $('#MyEditableId').on('mouseup', function(event) {
        var MyEditable = document.getElementById('MyEditableId');
        MyEditable.focus();
        range = document.createRange();

        // endOffset: It will be better the length of where actually was clicked, e.g. after 15-characters. But this.length will be also ok.
        endOffset = $(this).length;
        range.setStart(MyEditable.firstChild,0);
        range.setEnd(event.target,endOffset);
        var selection = window.getSelection();
        selection.addRange(range);

        // get html for your div  
        var myDiv = document.getElementById('MyEditableId');
        alert(myDiv.innerHTML);
    });
GibboK
  • 71,848
  • 143
  • 435
  • 658
  • Thanks, but I won't the entire content of DIV e.g. `$('#MyDiv').html()`. I will get the content of Div from 0 position to clicked position as HTML-Code, NOT as text. – user3815508 Oct 15 '14 at 10:41
  • Try this http://stackoverflow.com/questions/2444430/how-to-get-a-word-under-cursor-using-javascript, it shows how to select html using the cursor, I hope it can help you. – GibboK Oct 15 '14 at 11:57
1

Just change the alert line in your code to below one works well..

alert($.trim($('<div>').append(range.cloneContents()).html()));
Gaurang Patel
  • 4,310
  • 6
  • 27
  • 32
0

I was just going through the documentation for Range and selection. You could use the extractContents() or cloneContents() method supported by the Range object like so in your case Demo:

 var fragment = window.getSelection().getRangeAt(0).extractContents();

This automatically gets the first range that the user has selected. Although users can select multiple ranges by holding down the "Ctrl" Key. This gives the exact match till the cursor position for the simpler cases.

There are some caveats to this though. Both the methods extractContents() or cloneContents() return a documentFragment and the documentation clearly states that:

Event Listeners added using DOM Events are not copied during cloning. HTML attribute events are duplicated as they are for the DOM Core cloneNode method. HTML id attributes are also cloned, which can lead to an invalid document through cloning.

In essence, document fragments can contain invalid HTML and therefore you can not use all the normal DOM like .html() in some cases.

I found a relevant SO post on getting the cursor position on a contentEditable element and came across a TextRange Object (supported in IE < 9) and it has an htmlText property which returns the HTML source of the selection as a 'valid' HTML fragment. So in that case you would do something like:

 var fragment = document.selection.createTextRange().htmlText;

However since most of the modern browsers support Window.getSelection(), it's good practice that you use it and build upon the suitable methods you have at your disposal. Hope it gets you started in the right direction.

Sidenote - Also from the docs:

using a selection object as the argument to window.alert will call the object's toString method

Community
  • 1
  • 1
Vivek Pradhan
  • 4,777
  • 3
  • 26
  • 46
  • Thank you for detailed explanation. It is helpful. But `window.getSelection().getRangeAt(0).cloneContents();` delivers nothing (maybe it is to change a little) and the `document.body.createTextRange().htmlText;`delivers the entire HTML-Code. – user3815508 Oct 15 '14 at 11:54
  • @user3815508, I was giving you an example of `TextRange` object. I have edited the code snippet as per your context and also included a [jsfiddle](http://jsfiddle.net/4qu5aonv/) in the answer that you might want logs the document fragment from the selection into the console. Feel free to play around with it. – Vivek Pradhan Oct 15 '14 at 12:11