问题
I'm working on a Chrome extension that will extract a plain text url from a selection, but the selection will always be a fraction of the url, so I need to scan left and right. I basically need to extract 500 characters around the selection from innerText, since I don't want to parse html elements, and also don't want to re-assemble textContent's.
Here's what I have so far, it's working quite well, but I feel there's a better way that doesn't modify the document object and then restore it back to original state ...
// create a random 8 digit number - or bigger since we don't want duplicates
var randId = Math.floor(Math.random()*(90000000)+10000000);
var selection = document.getSelection();
var selectionRange = selection.getRangeAt(0);
// backup content, and then clone selection the user has made
var selectionContents = selectionRange.cloneContents();
var selectionContentsTxt = selectionContents.textContent;
// add random number to previous selection, this will expand selection
selectionContents.textContent = randId;
selectionRange.insertNode(selectionContents);
// find the random number in the document (in innerText in document.body)
var everything = document.body.innerText;
var offset = everything.indexOf(randId);
// restore backed up content to original state,- replace the selection
selectionContents = selectionRange.extractContents();
selectionContents.textContent = selectionContentsTxt;
selectionRange.insertNode(selectionContents);
// now we have the selection location offset in document.body.innerText
everything = document.body.innerText;
var extract = everything.substring(offset-250, offset+250);
extract holds the extracted text, with line breaks, etc, evaluated by the browser. This will by the way be Chrome only so I don't need cross compatibility at all. Now I can parse the selection - from middle to the edges to find the url, note that starting the parse from middle is important so I didn't just extract an innerText from a parentNode of my getSelection() without knowing the offsets ...
Is there a better way of doing this? maybe copying the entire document to a DOMParser, but then how do I apply the getSelection from the original document to it ?
------ UPDATE ------
I've simplified the code above (forgot to mention I'm working with mouse clicks so I detect event click, after a double click to select some text) and now it finds the caretOffset in document.body.innerText but it still modifies the document and then restores it, so still thinking of a better way to do this. I'm wondering if insertNode and deleteContents is bad in some way ?
var randId = Math.floor(Math.random()*(90000000)+10000000);
var range = document.caretRangeFromPoint(event.clientX, event.clientY);
range.insertNode(document.createTextNode(randId));
var everything = document.body.innerText;
var offset = everything.indexOf(randId);
range.deleteContents();
var everything = document.body.innerText;
var extract = everything.substring(offset-250, offset+250);
document.getSelection().anchorNode.parentNode.normalize();
Any thoughts?
来源:https://stackoverflow.com/questions/26540132/a-better-way-to-extract-innertext-around-getselection