Comment obtenir un mot sous le curseur à l'aide de JavaScript?
Si j'ai, par exemple, ont
<p> some long text </p>
sur ma page HTML, comment puis-je savoir que le curseur de la souris est pour l'exemple ci-dessus le mot "texte"?
- Cette démo en direct pour comment obtenir un mot sous le curseur à l'aide de JavaScript basé sur le code source fourni par Damovisa: jsfiddle.net/5gyRx.
- Il y a une nouvelle réponse à cette question par une prime. Vous pourriez envisager de choisir (pour le bien des nouveaux utilisateurs qui viennent).
Vous devez vous connecter pour publier un commentaire.
Plus pour les deux autres réponses, vous pouvez être en mesure de séparer vos paragraphes dans les travées de l'utilisation de jQuery (ou javascript en général).
De cette façon, vous n'auriez pas besoin de penser à la sortie de votre texte avec des envergures dans les mots. Laissez votre javascript le faire pour vous.
par exemple
Noter que le code ci-dessus, bien que cela fonctionne, enlèvent tout code html à l'intérieur de votre étiquette de paragraphe.
jsFiddle exemple
$(this).text().replace(/\b(\w+)\b/g, "<span>$1</span>")
au lieu de la boucle. Ceci permet de couvrir tous les espaces correctement.$('p')
sélecteur$('p,h1,h2,h3')
et ainsi de suite. De même, pour obtenir le hover pour le travail, vous aurez besoin de changer le deuxième sélecteur de$('p span,h1 span,h2 span,h3 span')
.Mon autre réponse ne fonctionne que sous Firefox. Cette réponse fonctionne dans Chrome. (Peut fonctionner dans Firefox, je ne sais pas.)
Dans votre gestionnaire mousemove, appel
getWordAtPoint(e.target, e.x, e.y);
range.endOffset
(et se termine àrange.endOffset + 1
). Donc, à moins que la condition est en faitwhile(currentPos < endPos)
le dernier caractère ne seront jamais testé.Préambule:
Si vous avez plusieurs travées et imbriquées HTML que séparer les mots (ou même des personnages dans les mots), alors toutes les solutions ci-dessus auront du mal à revenir à la pleine et correcte d'un mot.
Voici un exemple de la richesse question:
Х</span>rт0съ
. Comment retourner correctementХrт0съ
? Ces questions n'ont pas été abordées en 2010, de sorte que je vais vous présenter deux solutions (2015).Solution 1 - Bande intérieure balises, enveloppez s'étend autour de chaque mot:
Une solution est de supprimer les balises span à l'intérieur des paragraphes, mais de préserver leur texte. Diviser les mots et les phrases sont ainsi réunis en un ensemble comme du texte normal. Chaque mot trouvé par des espaces de la division (et pas seulement un espace), et ces mots sont enveloppés dans des travées qui peuvent être individuellement accessibles.
Dans la démo, vous pouvez mettre en surbrillance le mot en entier et d'obtenir ainsi le texte de l'ensemble de la parole.
Code:
JS:
HTML:
Solution 1 texte intégral de démonstration
Solution de 2 - Signe d'inspection et DOM transversal:
Ici est une solution plus complexes. C'est une solution algorithmique l'aide d'un noeud de la traversée qui compte avec précision correcte et complète le mot sous le curseur dans un nœud de texte.
Temporaire mot est trouvé, par la vérification de la position du curseur (à l'aide de
caretPositionFromPoint
oucaretRangeFromPoint
, les crédits pour l'idée de @chrisv). Cela peut ou peut ne pas être le mot complet, encore.Il est ensuite analysé afin de voir si elle est au bord de son nœud de texte (début ou à la fin). Si elle l'est, la précédente nœud de texte ou le texte suivant nœud est examiné pour voir si elle doit être réunis pour faire de cette parole de fragment plus.
Exemple:
Х</span>rт0съ
doit retournerХrт0съ
, pasХ
nirт0съ
.L'arborescence DOM traversée pour obtenir le côté non-barrière nœud de texte. Si deux mots fragments sont séparés par un
<p>
ou une autre barrière de la balise, puis ils ne sont pas adjacents et donc pas partie de la même parole.Exemple:
њб.)</p><p>Во
ne doit pas renvoyer deњб.)Во
Dans la démo, la gauche de la div flottante est le mot sous le curseur. Le droit div flottante, si visible, montre comment un mot sur une limite a été formé. D'autres balises peuvent en toute sécurité être en ligne serait avec le texte dans cette solution.
Code:
JS:
CSS:
HTML:
(Remarque: j'ai pris la liberté d'appliquer des styles à la durée de balises qui ont été présents dans votre exemple de code HTML pour éclairer l'endroit où le texte nœud frontières.)
Solution 2 texte intégral de démonstration
(Travail en Chrome et IE jusqu'à présent. Pour le savoir, une méthode de IERange a dû être utilisé comme une cale pour la compatibilité inter-navigateur)
À ma connaissance, vous ne pouvez pas.
Seule chose que je peux penser à est de mettre chacun des mots dans leur propre élément, puis appliquer de la souris sur les événements de ces éléments.
Il existe une API pour cela dans le courant de CSSOM Visualiser des projets:
document.caretPositionFromPoint(x,y)
Vous devez vérifier que le navigateur prend en charge ce, bien que. Firefox 7 semble ne pas le soutenir à tous, alors que les rapports de bug indiquer Firefox 9. Chrome 14 prend en charge
caretRangeFromPoint(x,y)
qui est essentiellement le même, mais à partir d'une ancienne CSSOM projet.Voici la solution pour le bounty.
Comme suggéré par chrisv vous pouvez utiliser
document.caretRangeFromPoint
(chrome) oudocument.caretPositionFromPoint
(Firefox).Je pense que cette solution mieux répondre à votre question car elle ne permet pas de modifier votre texte ou le DOM.
Cette fonction retourne le mot sous le curseur de la souris, sans modifier le DOM:
De la
document.caretRangeFromPoint
la documentation:De la
document.caretPositionFromPoint
la documentation:Les deux fonction sont légèrement différents, mais ils reviennent tous les deux le noeud contenant le texte et le décalage du curseur dans ce texte. De sorte qu'il est facile d'obtenir le mot sous la souris.
Voir l'exemple complet:
JS:
HTML:
Voici une solution simple qui fonctionne dans Chrome pour la plupart des cas:
Je laisse le filtrage de la ponctuation et de correctement gérer la césure des mots comme exercice pour le lecteur :).
Aw yiss! Voici ho!
Simple que cela et sans Jquery ou n'importe quel autre framework
Violon: https://jsfiddle.net/703c96dr/
Il mettra s'étend sur chaque mot et ajouter un onmouseover et onomouseout fonction. Je pourrais créer une classe simple pour le rendre plus utilisable, mais le code est si simple que n'importe qui peut modifier et utiliser.
Simple code
Vous aurait probablement pour briser le paragraphe, de sorte que chaque mot a été contenue à l'intérieur de son propre <span> élément, puis ajouter
onmouseover
attributs d'événement à chacun d'eux...Et je pense que vous voulez dire "<p>certains long texte</p>"; barres obliques inverses ne font pas partie de HTML.
Dans Firefox, vous pouvez associer l'événement mousemove. Le rappel a un argument, e. Dans le rappel, ce faire:
Maintenant str a l'ensemble du texte de la souris a été plus de. e.rangeOffset est l'emplacement du pointeur de la souris à l'intérieur de cette chaîne. Dans votre cas, str serait "texte très long" et.e.rangeOffset serait 11 si vous avez été sur le "e" dans "texte".
Ce code va être un peu confus si vous êtes dans les marges, par exemple lorsque le pointeur de la souris est sur la même ligne que le texte, mais après la fin de celui-ci. Pour résoudre ce problème, vous devez vérifier que vous êtes en fait en haut du texte. Voici le test:
Cette technique fonctionne dans Firefox. Ne fonctionne pas sous Chrome.
JS:
CSS:
HTML:
Ma réponse est dérivé de Drakes' "Solution 2 - Signe d'inspection et DOM traversée". Merci beaucoup à Drakes pour pointer vers cette solution!
Cependant, il y a deux problèmes avec les Drakes solution 2 lorsque l'on travaille sur IE. (1) le décalage calculé est incorrect, et (2) trop complexe, beaucoup de code.
Voir ma démonstration sur JSFiddle à ici.
Pour le problème 1, si vous cliquez quelque part à propos de la dernière ligne du texte, par exemple quelque part dans "l'épaule de porc longe de shankle turducken tige de la vache. Bacon ballon de la pointe de surlonge de jambon.", vous pouvez remarquer le décalage calcul est différent avec IE (solution originale) et IE méthode 2 (ma solution). Aussi, les résultats de l'ei méthode 2 (ma solution) et à partir de Chrome, Firefox sont les mêmes.
Ma solution est bien plus simple. Le truc, c'est, après l'utilisation TextRange pour faire une sélection à la position X/Y, obtenir un type de IHTMLSelection en appelant le document.getSelection(). Cela ne fonctionne pas pour IE<9 mais si c'est OK pour vous, cette méthode est beaucoup plus simple. Un autre inconvénient est, avec IE la méthode des effets secondaires (comme la méthode originale) est le changement de sélection (c'est à dire perdre de l'utilisateur d'origine de la sélection).