views:

72

answers:

1

It is possible to get whatever the user has selected with the mouse using Javascript, like this: http://www.motyar.info/2010/02/get-user-selected-text-with-jquery-and.html

My issue is that I do not just need this text, but I also need:

  1. to get the html surrounding this text (eg. if the user selects "hello" and this hello is in the source produced as: "<div><span>hello</span></div>" that is what it should return).

  2. to do the same for graphics

Can anyone guide me through this process, or are there alternatives if this is not possible?

+1  A: 

This will do it in all major browsers. There are separate branches for IE and more standards-compliant browsers. In IE, it's slightly easier because the proprietary TextRange object created from the selection has a handy htmlText property. In other browsers, you have to use the cloneContents() method of DOM Range to create a DocumentFragment containing a copy of the selected content and obtain the HTML from this by appending the fragment to an element and returning the element's innerHTML property.

function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}

alert(getSelectionHtml());
Tim Down
Thanks, this seems promising. However, when I select only text, I often do not receive the tag that the text is contained in. While if I select a bit more (eg. some whitespace too) it does seem to return the tag that the text is contained in. Basically, I would just want to get the text that is selected and then choose howmany levels above this text I receive. Eg. <div><p>test</p></div> should return test, <p>test</p> or <div><p>test</p></div> depending on the level given (0, 1, 2 respectively). Is that possible?
Tom
@Tom: What would you want to do in a situation such as `<div><p><b>o|ne</b></p><p>tw|o</p></div>` (pipes denote selection boundaries)? Here, you've got a selection whose boundaries are at different levels.
Tim Down
Good remark. Thinking about it, I maybe should rephrase my question/needs. What I need is an array with the html to the left of the selection, the html of the selection and the html to the right of the selection. So in your case: arr[0] = <div><p><b>o, arr[1] = ne</b></p><p>tw, arr[2] = o</p></div>. On another note, I read at http://www.quirksmode.org/dom/range_intro.html that browsers automatically add ending tags if you get a broken part of html with the selection, not sure if this is true (in all cases) though.
Tom
If the above is enough reason for me to post a new question and accept this one, please do tell me.
Tom
Can I ask why you need this? It's not straightforward and seems unnatural to me. You're right, browsers do return valid HTML representing the selection so that it can be inserted elsewhere in the document. In the case of IE, it returns a string while other browsers return a `DocumentFragment` node. It's generally safer to consider portions of an HTML document in terms of nodes in the document rather than HTML string representations.
Tim Down
Tim Down, I'm working on a visual scraper for which the user selects something in the website. I then need to get the exact html surrounding the selection, so that I can refind this part when it dynamically changes.
Tom
Like I said though, if this requires a new question tell me. I guess you already answered my original question (I should have been more precise).
Tom
I'd say this is all the same question really. I'm still not clear what you're trying to achieve. So, the user selects something in your page, presses a button or something, and then what happens? Later you want to recreate the selection, but what could have happened to the document in the meantime?
Tim Down
@ Tim Down, is that very relevant? Basically, the user selects content that is dynamic (eg. a book's title on a book website). I then need to get the html surrounding this book title. Eg. arr[0] = "...<h1 id='title'>", arr[1] = "The <b>Emperor</b>", arr[2] = "</h1>..." where 0 is left, 2 is right and 1 is selected html. Now, when the user goes to a page with a different book but the same page structure (as it is dynamically pulled from database), I can use arr[0] and arr[2] to retreive whatever is in the center of these 2 parts (which is the new book title). Hope you understand. Thanks.
Tom