Search This Blog

Saturday, February 14, 2009

Getting the HTML of a Range Created in JavaScript


Working on a mainly JavaScript-driven rich-text editor for the discussion forum on Mr. Renaissance, I wanted to include a feature that automatically inserted block quotations. Two days after the editor's debut, I suddenly noticed that this feature was losing its formatting: all line breaks and markup were gone, in its place one large, crunched-together paragraph that even ran sentences together in places.

A bit of Googling revealed that using range to retrieve the user's selection returns plain text (at least in non-IE browsers), not its formatted HTML:
The contents of userSelection

The userSelection variable is now either a Mozilla Selection or a Microsoft Text Range object. As such it grants access to all methods and properties defined on such objects.

However, the Mozilla Selection object that userSelection refers to in W3C-compliant browsers also contains the text the user has selected (as text, not as HTML).

From Introduction to Range, emphasis mine.
Frustrating, to say the least. I won't go into a list of all the things I tried, but I finally found the following (slightly modified) snippet of code at Snipplr, courtesy of David King of the entirely open-source OOPStudios in Newcastle, UK:
var getSelectionHTML = function() {
    var s;
    if (window.getSelection) {
        // W3C Ranges
        s = window.getSelection();
        // Get the range:
        if (s.getRangeAt) var r = s.getRangeAt(0);
        else {
            var r = document.createRange();
            r.setStart(s.anchorNode, s.anchorOffset);
            r.setEnd(s.focusNode, s.focusOffset);
        }
        // And the HTML:
        var clonedSelection = r.cloneContents(),
            div = document.createElement('div');
        div.appendChild(clonedSelection);
        return div.innerHTML;
    } else if (document.selection) {
        // Explorer selection, return the HTML
        s = document.selection.createRange();
        return s.htmlText;
    } else {
        return '';
    }
};
I am pleased to report that David has created a wonderful little function that returns the HTML of the user's selection rather than just plain, unformatted text.

Note: If you want to simulate the action of Cut (rather than Paste), change r.cloneContents() to r.extractContents(). Normally, there would be no reason to do so, but it is a possibility.

3 comments:

  1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me..I am a regular follower of your blog.
    Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from HTML5 CSS3 Javascript Online Training from India .
    or learn thru HTML5 CSS3 Javascript Online Training from India. Nowadays JavaScript has tons of job opportunities on various vertical industry. HTML5 CSS3 Javascript Online Training from India


    ReplyDelete
  2. It is nice that I can read these messages.
    June

    ReplyDelete