Quantcast
Channel: sixserv blog » Web
Viewing all articles
Browse latest Browse all 10

JavaScript: onMouseMove Google Translation

$
0
0

I wanted to implement a JavaScript onMouseMove Event, that translates the word under the mouse pointer with the Google Translator. I want to share the following solution.

I split this into the following two separate problems:

First: Detect word for an onMouseMove Event

The onMouseMove Event can listen on any Element for mouse movements. To detect the word under the mouse pointers position, I utilize the W3C(DOM-2) specified Range Object.

Most modern browsers support the Range object, but the event.rangeParent Attribute seems to be only supported by Firefox. Currently I’ve no cross-browser solution for this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
 * Apply offset to range and extract a single character at position.
 *
 * range -- the range object effected
 * originalOffsetStart, originalOffsetEnd -- Start offsetStart and offsetEnd
 * offset -- the relative offset to apply
 */
function getRangeCharacter(range, originalOffsetStart, originalOffsetEnd, offset) {
    var character = ' ';
    try {
        range.setStart(range.startContainer, originalOffsetStart + offset);
        range.setEnd(range.startContainer, originalOffsetEnd + offset);
        character = range.toString()[0];
        range.setStart(range.startContainer, originalOffsetStart - offset);
        range.setEnd(range.startContainer, originalOffsetEnd - offset);
    } catch (e) {}    
 
    return character;
}
 
/**
 * Returns a single word for the given event.
 */
function getEventWord(evt) {
    if (!evt.rangeParent || !document.createRange) {
        return '';
    }
 
    var range = document.createRange();
 
    range.setStart(evt.rangeParent, evt.rangeOffset);
    range.setEnd(evt.rangeParent, evt.rangeOffset);
 
    // the word ends when this characters appears
    var stop_character_pattern = /^[\W]$/m;
 
    // this "overwrites" some characters from the above pattern
    var ignore_stop_character_pattern = /^['|\-]$/;
 
    // I assume startOffset == endOffset so set 1 character selection ...
    var originalOffsetStart = range.startOffset;
    var originalOffsetEnd = range.startOffset + 1;
    try {
        // test:
        range.setStart(range.startContainer, originalOffsetStart);
        range.setEnd(range.startContainer, originalOffsetEnd);
    } catch (e) {
        // out of bounds
        originalOffsetStart -= 1;
        originalOffsetEnd -= 1;
        range.setStart(range.startContainer, originalOffsetStart);
        range.setEnd(range.startContainer, originalOffsetEnd);
    }
 
    // First Step: Find left end of word:
    var leftCharacterPos = 0;
    var iChar = '';
    for (var iOffStart = 0; iOffStart <= originalOffsetStart; iOffStart++) {
        iChar = getRangeCharacter(range, originalOffsetStart, originalOffsetEnd, -1 * iOffStart);
 
        leftCharacterPos = iOffStart;
 
        if (stop_character_pattern.test(iChar) && !ignore_stop_character_pattern.test(iChar)) {
            // remove the stop character!
            leftCharacterPos -= 1;
            break;
        }
    } leftCharacterPos = originalOffsetStart - leftCharacterPos;
 
    // Last Step: Find right end of word:
    var rightCharacterPos = 0;
    for (iOffStart = 0; true; iOffStart++) {
        iChar = getRangeCharacter(range, originalOffsetStart, originalOffsetEnd, iOffStart);
 
        if (stop_character_pattern.test(iChar) && !ignore_stop_character_pattern.test(iChar)) {
            rightCharacterPos = iOffStart - 1;
            break;
        }
    } rightCharacterPos = originalOffsetEnd + rightCharacterPos;
 
    try {
        range.setStart(range.startContainer, leftCharacterPos);
        range.setEnd(range.startContainer, rightCharacterPos);
    } catch (e1) {
        range.detach();
        return '';
    }
 
    var retWord = range.toString();
 
    range.detach();
 
    return retWord;
}

Second: Translate Text with Google Translator

This is very easy because Google provides an very easy to use Ajax API for this (attend the possible google user tracking!):

1
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// read onMoveTranslate()
var last_word = null;
var timeout = null;
var word_cache = [];
 
/**
 * Translate text For onmousemove events.
 */
function onMoveTranslate(event) {
    // get element the translation should appear in:
    var translation = document.getElementById('translation');
 
    var word = getEventWord(event);
    if (!word || word == '') {
        return;
    }
 
    if (typeof(word_cache[word]) !== 'undefined') {
        translation.innerHTML = word_cache[word]; //+" (cached)";
        return;
    }
 
    if (word != last_word) {
        if (timeout) {
            window.clearTimeout(timeout);
        }
 
        translation.innerHTML = 'Translating ... ' + word;
        timeout = window.setTimeout(function(){
            google.language.translate(word, 'en', 'de', function(result) {
                if (!result.error) {
                    translation.innerHTML = result.translation;
                    word_cache[word] = result.translation;
                }
            });
        }, 800);
    }
    last_word = word;
}
 
google.load("language", "1");

At last I assign the onMouseMove Event to the onMoveTranslate() function:

1
<div id="content" onmousemove="onMoveTranslate(event);">

Here is an full Example for this.


Viewing all articles
Browse latest Browse all 10

Trending Articles