On Text Highlight Event?

JavascriptFirefox AddonDom Events

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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]

Solution 2 - Javascript

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.

Solution 3 - Javascript

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);

Solution 4 - Javascript

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?

Solution 5 - Javascript

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 &lt;p&gt; 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>

Solution 6 - Javascript

You can use selection change event for this

    document.addEventListener('selectionchange', (e)=>{
        console.log("Archor node - ",window.getSelection().toString());
    });


Solution 7 - Javascript

The solution using the mouseup trick is not the proper solution. That is a hacky way and not perfect. Less efficient too as you are now catching mouseups for so much crap.

The real way to do it in Firefox addon is to use addSelectionListener see this topic: https://stackoverflow.com/questions/22216324/observe-for-highlight

Now even if user uses keyboard to make selections it is caught.

Credit to Neil for tipping me off on where to find it on MXR

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobert SmithView Question on Stackoverflow
Solution 1 - JavascriptRobertView Answer on Stackoverflow
Solution 2 - JavascriptPatrick EvansView Answer on Stackoverflow
Solution 3 - JavascriptjarsbeView Answer on Stackoverflow
Solution 4 - JavascriptwaffledonkeyView Answer on Stackoverflow
Solution 5 - JavascriptMarshalView Answer on Stackoverflow
Solution 6 - JavascriptMD SHAYONView Answer on Stackoverflow
Solution 7 - JavascriptNoitidartView Answer on Stackoverflow