web-dev-qa-db-fra.com

Sur l'événement de surbrillance de texte?

Je suis curieux de savoir si quelqu'un sait comment déclencher une fonction à exécuter si/une fois que l'utilisateur a fini de sélectionner du texte sur la page Web? Je voudrais que l'utilisateur puisse sélectionner du texte, et après un court délai (ou immédiatement, à ce stade, cela n'a pas beaucoup d'importance) un bouton de superposition apparaît près du texte que l'utilisateur peut ensuite cliquer et je reviens en arrière et exécute plus de mon code qui est basé sur la sélection. C'est pour une extension Firefox.

Un exemple similaire auquel je peux penser serait comme dans IE où vous pouvez sélectionner du texte et ensuite cela fait apparaître les "accélérateurs Web". Je suis sûr à 99% que je sais comment je le ferais réellement superposer le bouton et obtenir la position du texte sélectionné, mais je ne sais pas comment vérifier s'il y a quelque chose de sélectionné, sans faire une sorte de boucle infinie, ce qui semble être une idée terrible.

ÉDITER:

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

C'est donc ce que j'ai trouvé en utilisant la suggestion de Robert, et il m'a fallu un certain temps pour tout mettre au bon endroit, mais cela fonctionne très bien! Maintenant, pour positionner mon bouton.

58
Robert Smith

Il n'y a pas de onhighlightext ou quelque chose comme ça, mais une solution serait de lier onmouseup pour vérifier si du texte est sélectionné s'il ne se trouve pas dans un input/textarea.

Éditer

Voici un exemple d'implémentation pour vous. Je n'ai testé cela que dans Chrome/Firefox/IE7. Cela fonctionne également dans les entrées.

http://jsfiddle.net/qY7gE/

Code de 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]
71
Robert

Un peu tard pour la fête mais pour référence future ...

Jetez un œil à l'événement DOM select sur MDN .

Il se déclenche une fois que la souris ou la touche est relâchée (au moins dans Chrome 40).

document.addEventListener('select', callback);

8
jarsbe

Il existe un événement natif pour lorsqu'une sélection de texte est effectuée/modifiée. selectionchange a prise en charge de base sur la plupart des navigateurs, y compris IE , et fonctionnera pour tout texte dans un document et pas seulement pour les éléments de formulaire.

document.addEventListener("selectionchange",event=>{
  let selection = document.getSelection ? document.getSelection().toString() :  document.selection.createRange().toString() ;
  console.log(selection);
})
select this text

Remarque, comme son nom l'indique, il se déclenche lors de toute modification d'une sélection. Ainsi, vous recevrez plusieurs appels vers votre fonction de rappel lorsque vous sélectionnez du texte.

5
Patrick Evans

Je pense que @ patrick-evans avait la bonne réponse. C'est facilement la réponse la plus avant-gardiste et prise en charge par l'API - il vous suffit de repousser l'événement pour arrêter le déluge.

Je ne peux pas poster de réponse, mais considérez ceci

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?
1
waffledonkey

Je suggère d'écouter l'événement mouseup plutôt que le changement de sélection car ce dernier déclenche un grand nombre d'événements (jusqu'aux caractères sélectionnés), vous devez attendre une période arbitraire pour obtenir la sélection finale. Idem @Robert et @Makyen, je vous ai créé du code pour jouer:

<!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>
1
Marshal

La solution utilisant l'astuce de la souris n'est pas la bonne solution. C'est un moyen hacky et pas parfait. Moins efficace aussi car vous attrapez maintenant des souricières pour tant de merde.

La vraie façon de le faire dans l'addon Firefox est d'utiliser addSelectionListener voir cette rubrique: Observez-vous pour le surlignage?

Maintenant, même si l'utilisateur utilise le clavier pour effectuer des sélections, il est capturé.

Nous remercions Neil de m'avoir indiqué où le trouver sur MXR

0
Noitidart

Il suffit de gérer l'événement mouseup, car un utilisateur "lâche" la clé après avoir mis en surbrillance:

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()"
})
0
Cybernetic