0

Below is a snippet of the HTML. I'm trying to color the background of the tag that contains "Bananas".

<frame src="blah" name="navigation">
    <table id="menu">
        <tbody>
            <tr>
                <td>
                    <table>
                        <tbody>
                            <tr>
                                <td>
                                    Apples
                                </td>
                                <td>
                                    <input class="button">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
            <tr>
                <td>
                    <table>
                        <tbody>
                            <tr>
                                <td>
                                    Bananas
                                </td>
                                <td>
                                    <input class="button">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
            <tr>
                <td>
                    <table>
                        <tbody>
                            <tr>
                                <td>
                                    Carrots
                                </td>
                                <td>
                                    <input class="button">
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
        </tbody>
    </table>
</frame>

This is my JavaScript:

var t = navigation.document.getElementById("menu");
var trs = t.getElementsByTagName("tr");
var tds = null;

for (var i=0; i<trs.length; i++)
{
    tds = trs[i].getElementsByTagName("td");
    for (var n=0; n<trs.length;n++) {
        if(tds[n].innerHTML == "Bananas") {
          tds[n].bgcolor="#FF0000";
       }
    }
}

To be honest it's stumbling even on the 2nd line so I'm clearly doing something wrong. Can anyone suggest an efficient way to do this please?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
David
  • 1,222
  • 1
  • 8
  • 18

3 Answers3

2

This should do the job:

var table = document.getElementById('menu');
var tds = table.querySelectorAll('td');

for (var i = 0; i < tds.length; i++) {
  var td = tds[i];
  if (td.innerHTML.trim() === 'Bananas') {
    td.style.backgroundColor = 'red';
  }
}
  • Thank you... for some reason it's still refusing to execute that 2nd line... but I like this querySelectorAll method... – David Dec 19 '16 at 21:53
  • @David, what is the error you get? You can check it by opening dev tools and checking the console tab. – Lajos Arpad Dec 19 '16 at 23:28
1

You should use tds[n].innerText instead of tds[n].innerHTML

Difference between innerText and innerHTML in javascript

Community
  • 1
  • 1
Siamand
  • 1,080
  • 10
  • 19
1

This is a jquery-based solution:

//See: http://stackoverflow.com/questions/8779728/getting-element-within-frame-using-jquery
$("td", window.parent.frames[0].document).filter(function() {
    return this.innerText.indexOf("Bananas") + 1;
}).css("background-color", "yellow");

This is a plain Javascript solution:

var items = window.frames[0].document.getElementsByTagName("td");
for (var item in items) {
    if ((items[item].innerText) && (items[item].innerText.indexOf("Bananas") + 1)) {
        items[item].style["background-color"] = "yellow";
    }
}

However, it is nice to make things customizable, reusable. In our case, we could do a function. jquery version:

function jQueryBanana(context, test, operation) {
    context.filter(function() {
        test(this);
    }).operation($(this));
}

Usage:

jQueryBanana($("td", window.parent.frames[0].document), function(record) {
    return record.innerText + (record.innerText.indexOf("Bananas") + 1);
}, function(record) {
    record.css("background-color", "yellow");
});

Plain Javascript function

function vanillaBanana(items, test, operation) {
    for (var item in items) {
        if (test(items[item])) operation[items[item]];
    }
}

Usage:

vanillaBanana(window.frames[0].document.getElementsByTagName("td"), function(record) {
    return record.innerText && (record.innerText.indexOf("Bananas") + 1);
}, function(record) {
    record.style["background-color"] = "yellow";
});

This way of making your code more generic wll help you a lot in the long run.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Thanks so much for this amazing answer. I'm desperately trying to get it to work, currently failing, will keep trying. My page has two frames, and we're looking in the first one. I can't get it to run a single line of code right now... (I'm testing that by placing an alert between lines)... will keep trying tomorrow, also with tampermonkey in Chrome... thanks so much. – David Dec 20 '16 at 23:13
  • @David you are welcome, but we should reach a solution to your problem. Try debugging with dev tools, please share the details of your problem, including the line where the problem occurs and the error message. If you do that, we will find the solution in an easier manner. – Lajos Arpad Dec 21 '16 at 09:21
  • Hi Lajos, sorry for delay, I marked your answer as the solution because it's so good, socomprehensive, and I tested it in a more controlled environment and it works great. There's some fishy stuff happening on this third party database, and there are clearly some extra layers that are tripping me up. I'm low on time to continue so I'm parking it for now. Thanks so much for your answer, I know others will appreciate it too. – David Jan 01 '17 at 21:57
  • @David thank you for the feedback and I am glad I could help. You can ask about the database problem and possibly share the new question's link here so I can help. – Lajos Arpad Jan 02 '17 at 08:49