2

Do you know the most efficient way to highlight word and add onmouseover event?

I have text and I want to make somekind of word explanation field, so when user put his cursor on the word, I call AJAX to dictionary and show him meaning.

I have two ideas: 1) Before showing text, put each word to <span onmouseon="my_foo("word");"> wrapper. For example:

<span onmouseon="my_foo("Hello");">Hello</span>
<span onmouseon="my_foo("world");">world</span>

But I think this will seriously overload the page.

2) When user hold cursor for more than 0.5 sec in one area, I get pointer coordinates, calcuate what word is shown (I do not know if is possible) and do AJAX call.

What do you think is better, more easier to code?

Sergio
  • 28,539
  • 11
  • 85
  • 132
Tigran
  • 1,049
  • 3
  • 15
  • 31
  • I don't think 2 is possible because of differences between font rendering in different browsers. you would never know exactly which word it was. I would wrap everything either server side. or onLoad wrap everything in spans. On hover of any span with that class would ajax call – Adam Merrifield Dec 13 '13 at 12:43
  • 1
    2 is possible. But you will face issues for different browsers. I did implemented an annotation functionality same way. It was tough. for 1, there is a better way inside the event function definition you can get the inner text of the span so you do not need to put the string inside each call. – A Paul Dec 13 '13 at 12:45
  • What about performance in case 1? Was it fine? I mean text of 5000 words, for example. – Tigran Dec 13 '13 at 12:49

5 Answers5

4

First highlight the word under the cursor then show the meaning of it, check my fiddle: http://jsfiddle.net/shahe_masoyan/z7nkU/1/

HTML

    <div>
        <span>This text is a test text</span>
    </div>

JavaScript

$('div').each(function() {
    var $this = $(this);
    $this.html($this.text().replace(/\b(\w+)\b/g, "<span>$1</span>"));
});

$('div span').hover(
    function() { 
        $(this).css('background-color','#ffff66'); 
        alert(getTheMeaningOfTheWord($(this).html()));
    },
    function() { 
        $(this).css('background-color',''); 
    }
);

function getTheMeaningOfTheWord(word){

    return word+' = theMeaning';
}
Shahe
  • 964
  • 2
  • 13
  • 34
  • Do I need to refresh DOM or something else. I did as trial: some And onmouseover work, but hover not. – Tigran Dec 13 '13 at 13:18
  • you don't need to refresh anything, did you run the fiddle? – Shahe Dec 13 '13 at 13:22
  • @Tigran see my code in the fiddle, I don't have any onmouseover function on my span – Shahe Dec 13 '13 at 13:27
  • Will it work, in iframe? I tried you code. I already separated to spans and give class name. So I use: $('word_in_text').hover(). May be I did someting wrong, but will it work, in iframe? – Tigran Dec 13 '13 at 13:36
  • 1
    `$('word_in_text')` is invalid jquery selector, you have to put the id of the span or the element like this: `$('#word_in_text')`. Can you show me your code in a fiddle? – Shahe Dec 13 '13 at 13:38
  • I am not sure that it will work, too many js libraries. And my problem is when I put it into TinyMCE. If I put it into main page - no problem. Onmouse works fine, but non your solution, even css class style do not work. – Tigran Dec 13 '13 at 13:42
  • I am sorry, I can't help you with TinyMCE, but as you see in the fiddle the works fine and as you requested, anyways, good luck finding a solution. – Shahe Dec 13 '13 at 13:45
  • I found a solution and the problem was that TinyMCP loaded content dinimically and it strange way. JQuery did not look inside frame. That is solution: $($(document).contents().find('iframe').contents().find('.word_in_text')).hover(.... Thank you! – Tigran Dec 13 '13 at 13:59
  • @Tigran Good to know that you found a solution :) Hachogh – Shahe Dec 16 '13 at 05:37
1

I think 1 is simple and can be done this way:

Fiddle: http://jsfiddle.net/9d227/

HTML

<div id="yourDiv" style="Display: none;">your Text Here</div>
<div id="yourActualDiv"></div>

JQuery

var wordArray = $('#yourDiv').html().split(' ');
var totalString = "";
for(var i=0;i<wordArray.length;i++)
    totalString += "<span>" + wordArray[i] + " </span>";
$('#yourActualDiv').html(totalString);
var ConcurrenyFlag = 0;
$('#yourActualDiv span').mouseover(
    function()
    {
       if(ConcurrenyFlag == 0)
       {
           ConcurrenyFlag = 1;
           // Your code here.
           ConcurrenyFlag = 0;
       }
    }
)

This way, you only need to put your text in the yourDiv. The javascript code will handle the rest for you.
Hope this helps you.

The ConcurrenyFlag will help in reducing the load on client as only one code part will run at a time.

Ganesh Jadhav
  • 2,830
  • 1
  • 20
  • 32
1

Something like this should do something close to what you're looking for.

$('.addWordDictionary').html('<span>'+$('.addWordDictionary').html().replace(/ {1,}/g, '</span> <span>')+'</span>');

But, as you said it may be client intensive especially if there is a lot of text.

Adam Merrifield
  • 10,307
  • 4
  • 41
  • 58
1

You can use Lettering.js to solve this

http://letteringjs.com/

Simplified example:

http://jsfiddle.net/Zzxpx/

HTML:

<div class="w">"You will die of suffocation, in the icy cold of space"<div>

JS:

$(".w").lettering('words');
Magnus Engdal
  • 5,446
  • 3
  • 31
  • 50
1

I've made this stuff : http://jsfiddle.net/wared/eAq9k/. Requires a textarea and works by clicking instead of hovering. More details about getCaret() here : https://stackoverflow.com/a/263796/1636522.

<textarea readonly>Lorem ipsum</textarea>
textarea {
    display: block;
    width: 100%;
    border: none;
    resize: none;
    outline: none;
    margin: .5em 0;
}
$(function () {
    var el = $('textarea'),
        text = el.text();
    el.click(function () {
        var i = getCaret(this),
            w = getWord(text, i);
        $('p').text(i + ' : "' + w + '"');
    });

    // https://stackoverflow.com/a/995374/1636522

    el[0].style.height = '1px';
    el[0].style.height = 25 + el[0].scrollHeight + 'px';
});

function getWord(s, i) {
    var r = /\s/g;
    while (i && !r.test(s[--i])) {}
    r.lastIndex = i && ++i;
    return s.slice(i, (
        r.exec(s) || { index: s.length }
    ).index);
}
Community
  • 1
  • 1