On Text Highlight Event?
I'm curious if anyone knows how I would trigger a function to run if/once the user finishes selecting text on the web page? I would like the user to be able to select text, and after a short delay(or immediately, at this point it doesn't matter much) an overlay button appears near the text that the user can then click and I go back and run more of my code that is based on the selection. This is for a Firefox extension.
A similar example that I can think of would be like in IE where you can select text and then it brings up the "web accelerators". I'm 99% sure I know how I would actually overlay the button, and get the position of the selected text, but I have no idea how to check to see if there is anything selected, without doing some sort of infinite loop, which just seems like a terrible idea.
EDIT:
//In my overlay.js with the rest of my sidebar code
isTextSelected: function () {
var myText = cqsearch.getSelectedText();
var sidebar = document.getElementById("sidebar");
var sidebarDoc = sidebar.contentDocument || document;
var curHighlightedDiv = sidebarDoc.getElementById("testDiv");
curHighlightedDiv.innerHTML = "Current text selection:" + myText;
}
};
//In my on firefox load function I added this
document.onmouseup = cqsearch.isTextSelected;
So this is what I have come up with using Robert's suggestion, and it took me some time getting everything in the right spot, but it works great! Now on to position my button.
There isn't any onhighlightext
or anything like that, but a solution would be to bind onmouseup
to check if any text is selected if this isn't in a input
/textarea
.
Edit
Here's an implementation example for you. I only tested this in Chrome/Firefox/IE7. This works in inputs as well.
http://jsfiddle.net/qY7gE/
Code from JSFiddle:
var t = '';
function gText(e) {
t = (document.all) ? document.selection.createRange().text : document.getSelection();
document.getElementById('input').value = t;
}
document.onmouseup = gText;
if (!document.all) document.captureEvents(Event.MOUSEUP);
<input type='text' id='input' />
In software, a stack overflow occurs when too much memory is used on the call stack. The call stack contains a limited amount of memory, often determined at the start of the program. The size of the call stack depends on many factors, including the programming language, machine architecture, multi-threading, and amount of available memory. When too much memory is used on the call stack the stack is said to overflow, typically resulting in a program crash.[1] This class of software bug is usually caused by one of two types of programming errors.[2]
There is a native event for when a text selection is made/changed. selectionchange
has basic support on most browsers, including IE, and will work for any text within a document not just form elements.
document.addEventListener("selectionchange",event=>{
let selection = document.getSelection ? document.getSelection().toString() : document.selection.createRange().toString() ;
console.log(selection);
})
select this text
Note, as its name implies it fires on any change of selection. So you will get multiple calls to your callback function as you select text.
A bit late to the party but for future reference...
Take a look at the select
DOM event on MDN.
It fires once the mouse or key is released (at least in Chrome 40).
document.addEventListener('select', callback);
I'd suggest listening to mouseup event rather than selectionchange as the latter fires quite many events (up to the chars selected), you have to wait some arbitrary period to get the final selection. Ditto @Robert and @Makyen, I've created some code for you to play:
<!DOCTYPE html>
<html>
<body>
<div onmouseup="showSelection()">
<p>Select some of the text. You can also listen to the mouseup event at the <p> level</p>
<p>Anthoer paragraph and text</p>
<input type="text" value="Hello world!" onselect="showSelection()">
</div>
Outside of div, selection won't work as there is no listener if you don't uncomment the line: document.onmouseup = showSelection
<script>
// document.onmouseup = showSelection // listen to the mouseup event at document level
function showSelection() {
console.log('Selection object:', window.getSelection()) // same as document.getSelection()
console.log('Selected text:', window.getSelection().toString())
}
</script>
</body>
</html>
I think @patrick-evans had the right answer. It's easily the most forward-thinking and API supported answer -- you just need to debounce the event to stop the deluge.
I'm not able to post a reply, but consider this
function debounce(fn, delay) {
let timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
};
document.addEventListener("selectionchange", debounce(function (event) {
let selection = document.getSelection ? document.getSelection().toString() : document.selection.createRange().toString() ;
console.log(selection);
}, 250));
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad est veniam facere culpa expedita optio iste labore doloremque autem illo, in voluptatibus error ea, ab reprehenderit placeat facilis animi iure?