I’m not really on top of my time management yet, but this was hard enough to find that I think it warrants a blog post anyway…
Have you ever tried looking up how to use Javascript to get the selected HTML in a browser window in a form that can then be sent via XMLHTTPRequest or fed into an ordinary form field? (eg. for POSTing to a quote-collector tool) It’s a surprisingly difficult piece of info to find. (Hence why I’m partly writing this as a reminder to myself)
First, you’ll probably end up visiting the QuirksMode Range Intro to learn about window.getSelection() in browsers like Gecko/Firefox and the equivalent Internet Explorer scripting, but all you’ll learn there is how to get the selection as plain text… and that’s no secret.
Once you’ve got the selection/range, things become a little trickier because, once again, Internet Explorer and everyone else do things differently. In Internet Explorer, it’s as simple as range.htmlText but in other browsers, it’s a little less obvious.
First, you call range.cloneContents() to get a DocumentFragment object. This is more or less equivalent to Copy (Ctrl+C) when copying and pasting things. Then you create a <div> element, use div.appendChild(clonedSelection), and then grab the HTML as text from div.innerHTML. Don’t go looking for ways to serialize DOM nodes to XML. It’s non-portable and a bit of a red herring.
Here’s my solution, descended from the complete code fragment I eventually found on a thread on the FCKEditor forums:
getSelectionHTML = -> # Everyone but IE supports DOM selections if window.getSelection sel = window.getSelection() # IE Selections (Must come last to avoid messing with Opera) else if document.selection return document.selection.createRange().htmlText # Fail safely else return ""
if sel.getRangeAt # Everything but IE and old Safari range = sel.getRangeAt(0) else # Old Safari range = document.createRange() range.setStart(sel.anchorNode, sel.anchorOffset) range.setEnd(sel.focusNode, sel.focusOffset)
# Convert the document fragment to a string div = document.createElement('div') div.appendChild(range.cloneContents()) return div.innerHTML
# For those of you who can't readily compile CoffeeScript into Javascript,# 1. Visit http://jashkenas.github.com/coffee-script/# 2. Click "Try CoffeeScript" and paste this into the left-hand pane# 3. Copy the result from the right-hand pane.Now that you know, why not create some interesting bookmarklets?

This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
