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.

Answers:

Answer

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

Answer

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 the any change of a selection. So you will get multiple calls to your callback function as you select text.

Answer

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>

Answer

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?

Answer

Just handle the mouseup event, since a user "lets go" of the key after highlighting:

Vanilla JS

//Directly within element
<p class='my_class' onmousedown="my_down_function()" onmouseup="my_up_function()">

//On element
my_element = document.querySelector('.my_class');
my_element.onmousedown = function (e) { my_down_function(e); };
my_element.onmouseup function (e) { my_up_function(e); };

jQuery

$('.my_class').mousedown(function() {
    my_down_function()
})
$('.my_class').mouseup(function() {
    my_up_function()
})

Azle

az.add_event('my_class', 1, {
    "type" : "mousedown",
    "function" : "my_down_function()"
})
az.add_event('my_class', 1, {
    "type" : "mouseup",
    "function" : "my_up_function()"
})
Answer

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: 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

Answer

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]

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.