If I for example have
<p> some long text </p>
on my HTML page, how can I know that cursor of mouse is for example above the word 'text'?
If I for example have
<p> some long text </p>
on my HTML page, how can I know that cursor of mouse is for example above the word 'text'?
In Firefox you can hook the mousemove event. The callback has one argument, e. In the callback, do this:
Now str has the entire text that the mouse was over. e.rangeOffset is the location of the mousepointer within that string. In your case, str would be "some long text" and e.rangeOffset would be 11 if you were over the "e" in "text".
This code will get a little confused if you are in the margins, for instance when the mouse pointer is on the same line as the text but after the end of it. To fix this, you need to check that you are actually on top of text. Here's the test:
This technique works in Firefox. Doesn't work in Chrome.
Preamble:
If you have multiple spans and nested HTML that separate words (or even characters in words), then all the above solutions will have trouble returning the full and correct word.
Here is an example from the bounty question:
Х</span>rт0съ
. How to properly returnХrт0съ
? These issues were not addressed back in 2010, so I will present two solutions now (2015).Solution 1 - Strip inner tags, wrap spans around each full word:
One solution is to strip out the span tags inside paragraphs but preserve their text. Split words and phrases are thus joined back together as regular text. Each word is found by whitespace division (not just a space), and those words are wrapped in spans which can be individually accessed.
In the demo, you can highlight the entire word and thus get the text of the whole word.
Code:
Solution 1 full-text demo
Solution 2 - Caret inspection and DOM traversal:
Here is a more sophisticated solution. It's an algorithmic solution using node traversal that accurately captures the full and correct word under a cursor in a text node.
A temporary word is found by checking the caret position (using
caretPositionFromPoint
orcaretRangeFromPoint
, credits for the idea to @chrisv). This may or may not be the full word, yet.It is then analyzed to see if it is at either edge of its text node (beginning or end). If it is, the previous text node or the following text node is examined to see if it should be joined to make this word fragment longer.
Example:
Х</span>rт0съ
must returnХrт0съ
, notХ
norrт0съ
.The DOM tree is traversed to get the next non-barrier text node. If two word fragments are separated by a
<p>
or some other barrier tag, then they are not adjacent and thus not part of the same word.Example:
њб.)</p><p>Во
should not returnњб.)Во
In the demo, the left floating div is the word under the cursor. The right floating div, if visible, shows how a word on a boundary was formed. Other tags can safely be inline'd with the text in this solution.
Code:
(Note: I took the liberty of applying styles to the span tags that were present in your sample HTML to illuminate where text node borders are.)
Solution 2 full-text demo
(Working in Chrome and IE so far. For IE, a method from IERange had to be used as a shim for cross-browser compatibility)
There is an API for this in the current CSSOM View draft:
document.caretPositionFromPoint(x,y)
You would have to check which browser supports this, though. Firefox 7 seems not to support it at all, whereas bug reports indicate Firefox 9 will. Chrome 14 supports
caretRangeFromPoint(x,y)
which is essentially the same, but from an older CSSOM draft.To my knowledge, you can't.
Only thing I can think of is to put each of the words in their own element, then apply mouse over events to those elements.
Further to the two other answers, you may be able to split your paragraphs up into spans using jQuery (or javascript generally).
That way, you wouldn't need to think about outputting your text with spans around the words. Let your javascript do it for you.
e.g.
Note that the above code, while it works, will strip out any html inside your paragraph tags.
jsFiddle example
Here is the solution for the bounty.
As suggested by chrisv you can use
document.caretRangeFromPoint
(chrome) ordocument.caretPositionFromPoint
(Firefox). I think this solution better answer your question as it doesn't alter your text or the DOM.This function return the word under the mouse cursor without altering the DOM:
From the
document.caretRangeFromPoint
documentation:From the
document.caretPositionFromPoint
documentation:The two function are slightly different but they both return the node containing the text and the offset of the cursor in this text. So it is easy to get the word under the mouse.
See the full example: