Skip to content

Instantly share code, notes, and snippets.

@Munawwar
Last active January 10, 2017 01:45
Show Gist options
  • Save Munawwar/1115251 to your computer and use it in GitHub Desktop.
Save Munawwar/1115251 to your computer and use it in GitHub Desktop.
IE8 polyfill for HTML5 Range object's startContainer, startOffset, endContainer and endOffset properties.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
/*
This code is a IE8 (and below), polyfill for HTML5 Range object's startContainer,
startOffset, endContainer and endOffset properties.
*/
(function () {
function findTextNode(node, text) {
//Iterate through all the child text nodes and check for matches
//As we go through each text node keep removing the text value (substring) from the beginning of the text variable.
do {
if(node.nodeType==3) {//Text node
var find = node.nodeValue;
if (text.length > 0 && text.indexOf(find) === 0 && text !== find) { //text==find is a special case
text = text.substring(find.length);
} else {
//cosole.log(node.nodeValue);
return {node: node, offset: text.length}; //nodeInfo
}
} else if (node.nodeType === 1) {
var range = document.body.createTextRange();
range.moveToElementText(node);
text = text.substring(range.text.length);
}
} while ((node=node.nextSibling));
return null;
}
/**
* @param {Boolean} startOfSelection Set to true to find the startContainer and startOffset,
* else set to false (to find endContainer and endOffset).
*/
function getSelectionInfo(range, startOfSelection) {
if(!range) return null;
var rangeCopy = range.duplicate(), //Create two copies
rangeObj = range.duplicate();
rangeCopy.collapse(startOfSelection); //If true, go to beginning of the selection else go to the end.
var parentElement = rangeCopy.parentElement();
//If user clicks the input button without selecting text, then moveToElementText throws an error.
if (parentElement instanceof HTMLInputElement) {
return null;
}
//console.log(parentElement.nodeName); //Should return the parent.
/* However IE8- cannot have the selection end at the zeroth index of
* the parentElement's first text node.
*/
rangeObj.moveToElementText(parentElement); //Select all text of parentElement
rangeObj.setEndPoint('EndToEnd', rangeCopy); //Move end point to rangeCopy
//rangeCopy.text gives you text from parentElement's first character upto rangeCopy.
//Now traverse through sibling nodes to find the exact Node and the selection's offset.
return findTextNode(parentElement.firstChild, rangeObj.text);
}
function getIERange() {
var range=window.document.selection.createRange(), //Microsoft TextRange Object
start = getSelectionInfo(range, true),
end = getSelectionInfo(range, false);
if (start && end) {
return {
commonAncestorContainer: range.parentElement(),
startContainer: start.node,
startOffset: start.offset,
endContainer: end.node,
endOffset: end.offset
};
}
return null;
}
if (!window.getSelection && window.document.selection) { //IE8-
window.getSelection = function () { //Gets the first range object
var range = getIERange();
return {
rangeCount: range ? 1 : 0,
getRangeAt: function () {
return range;
}
};
};
}
}());
function onBtnClick() {
var range=window.getSelection().getRangeAt(0);
if (range) {
console.log(range.startContainer.nodeValue.substr(range.startOffset));
console.log(range.startOffset);
console.log(range.endContainer.nodeValue.substr(0, range.endOffset));
console.log(range.endOffset);
}
}
</script>
</head>
<body>
<h3>Select some text and click the button</h3>
<pre>The quick brown fox <b>jumped</b> over the lazy dog</pre>
<input type="button" value="console.log current selection info" onclick="onBtnClick();" /><br/>
<br/>
Clicking the button above will print out the following:<br/>
<pre>console.log(range.startContainer.nodeValue.substr(range.startOffset));
console.log(range.startOffset);
console.log(range.endContainer.nodeValue.substr(0, range.endOffset));
console.log(range.endOffset);</pre>
</body>
</html>
@visnup
Copy link

visnup commented Aug 24, 2012

awesome. this is exactly what I was looking for.

@leonspok
Copy link

Thank you!

@BamseKalleAnka
Copy link

IE8 says theres an error, it needs a '}'

@REAL04
Copy link

REAL04 commented Jun 10, 2015

Perfect! work it works wonder for me.
kindly let us know under which Open source License this code you release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment