Skip to content

Instantly share code, notes, and snippets.

@aganzha
Forked from Munawwar/test.html
Created December 3, 2013 22:04
Show Gist options
  • Save aganzha/7778283 to your computer and use it in GitHub Desktop.
Save aganzha/7778283 to your computer and use it in GitHub Desktop.
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment