Back

javascript advice needed

#1
I have an html page with a japanese text like this:

Code:
<span class="終わる">終わっ</span>た

Where the class name contains the dictionary form of a word.

This is a single word but in the actual text I have thousands of words.

In addition at the end of the page there is a list of all the words contained inside the text with their definitions, so that when the user clicks a word, its definition appears.

So the code looks something more like this:

Code:
<span onclick="showdef('def1')"><span class="終わる">終わっ</span></span>た

...

<div class="def1">definition of 終わる</div>
<div class="def2"> ... ... ...

I have furigana too. This way the document is self-contained, in the sense that it has everything inside itself, definitions, furigana, dictionary form and so on, without any need of external add-ons, extensions, epwing and so on.

But now I want to add a feature, which is something similar to LingQ.
I've implemented it like this, I have a javascript variable which contains a list of words that I want to highlight inside the document.

For example if the list contains the word 終わる, a javascript function search inside the document for all the words enclosed in a <span> with the class "終わる" and it modifies its background-color to highlight them.

This is working ok, but it's incredibly slow if the words list it long (like 5000 words).

I've tried to remove the definitions from the page and it's faster, so it's obvious that the javascript function searches for every single element. This is the javascript:

Code:
highlights = highlights.split(" "); //this variable contains a list of words to highlight

function onbodyload()
{
  for(var i = 0; i < highlights.length; i++) { //for every word to highlight
    var allelemstohighlight = document.getElementsByClassName(highlights[i]); //let's check every element with that word as a classname
    for(var j = 0; j < allelemstohighlight.length; j++) {
      allelemstohighlight[j].style.backgroundColor = "#b8d7a3";
    }
  }
}

I've tried to resctict the search by using

Code:
document.querySelectorAll("div.content span.tooltip>span." + highlights[i]);

instead of getElementsByClassName, so in theory it would seach only inside <div="content"> </div> and exclude the definitions from the search because they are outside of that div. But it's not happening.

So my question is, is there any way to make it faster with javascript only without any use of outside libraries and the like?

Ok, I've half solved it by using a first getElementsByClassName to obtain only the content of <div class="content"> and then I search only inside of this. But now I see how I could improve it even more
Edited: 2018-02-01, 8:28 pm
Reply
#2
Ok, I've seen that LingQ itself splits long texts into chunks of 2000 words. I've done the same and now it's perfect.
Sorry for the bothering!
Reply
#3
(2018-02-01, 7:53 pm)cophnia61 Wrote: Ok, I've half solved it by using a first getElementsByClassName to obtain only the content of <div class="content"> and then I search only inside of this.
The ideal solution would be to not use classes in your definitions to begin with. Replace them with a custom data attribute (data-def-order = "1", for instance). Classes are for styling, and adding a bunch of classes to reach from JavaScript slows everything down and makes the code confusing.

I would even suggest using a custom data attribute in the text (data-stem, I guess), but I suspect that it might make your searches slower. Browsers optimize class search (by keeping an ordered master list of all classes), I don't know if they do that with custom attributes. If they don't, then your custom attribute search will slow down exponentially, with size...so don't do that.

It would be worth testing though, if you wish to refactor your code at some point. If there's no significant performance hit, the right thing to use is custom data attributes instead of classes.
Reply
Breakthrough Sale! Get 28% OFF Basic, Premium or Premium PLUS! (until March 2)
JapanesePod101
#4
I suggest using the definition list tag for your gloss markup.
Reply
#5
Thank Stansfield123 and fkb9g for the advices. In fact my output file looks like a mess and I want to refactor this.
Another thing that I want to add is to move functions calls from the inline html to an event listener but it looks more complicated that I thought xD
About the speed issue, I solved by upgrading the collection. Every time a word to highlight is found, the element is removed from the collection, so the next search won't check the words already highlighted.
Reply