0

I try to highlight on my page the search expression with a button. Can anyone help me please to solve this problem?

Uncaught TypeError: Cannot read property 'indexOf' of undefined at highlight (?q=Python:11) at HTMLButtonElement.onclick (?q=Python:24)

The JS code:

function highlight(text) {
        var titles = document.getElementsByClassName('title');
        for (var x in titles) {
            var innerHTML = titles[x].innerHTML;
            var index = innerHTML.indexOf(text);
            if (index >= 0) {
                innerHTML = innerHTML.substring(0, index) + "<span class='highlight'>" + innerHTML.substring(index, index + text.length) + "</span>" + innerHTML.substring(index + text.length);
                x.innerHTML = innerHTML;
            }
        }
    }

Line 11:

var index = innerHTML.indexOf(text);

Line 24:

<button onclick="highlight('{{ search_expression }}')">Highlight search expression</button>
yunandtidus
  • 3,847
  • 3
  • 29
  • 42
  • 2
    Possible duplicate of [Why is using "for...in" with array iteration a bad idea?](https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea) – NineBerry Jun 07 '18 at 09:05
  • @NineBerry well that's the correct answer, but the question is not the same I think :) – Fabio Lolli Jun 07 '18 at 09:11

2 Answers2

2

Don't use for .. in to iterate over the list of elements, but a traditional for loop.

function highlight(text) 
{
        var titles = document.getElementsByClassName('title');
        for (var i=0; i < titles.length; i++) 
        {
            var title = titles[i];
            var innerHTML = title.innerHTML;

            // Work with title some more.
        }
}

For an explanation what is happening see Why is using "for...in" with array iteration a bad idea?

NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • I'd just like to add you could replace `for .. in` with `for .. of`, which is for looping enumerables. Differently from `for .. in`, with `for (let x of yourArray)` in each loop `x` would be assigned a value in the array - but I'd reccomend looping through indexes, it's more explicit and you're sure about what is happening. – Fabio Lolli Jun 07 '18 at 09:16
  • `for .. of` is not supported in Internet Explorer, so not an alternative if you cannot control what browsers are used. One could use `foreach()` on the collection instead. – NineBerry Jun 07 '18 at 09:22
  • Thanks a lot, working with the help of the other answer below. – Gergely Kudó Jun 07 '18 at 10:38
0

innerHTML might be undefined. You have to check if innerHTML is defined before calling innerHTML.indexOf

var innerHTML = titles[x].innerHTML
if (innerHTML) {
  var index = innerHTML.indexOf(text)
  ...
}
lipp
  • 5,586
  • 1
  • 21
  • 32