Search code examples
javascriptinnerhtmltampermonkey

How to read nested innerHtml and add background to parent?


I'm having trouble working through a webpage - I need to find some known innerHtml in a table, and affect the parent tag of the tag that contains the innerHtml. Afraid I have little to no JavaScript game...

The HTML looks like the below:

<table> <tbody>
    <tr class="header">
        <td>
            <table> <tbody>
                <tr class="header">
                    <td> <u> January </u> </td>
                    <td>foo</td>
                </tr>
            </tbody> </table>
        </td>
    </tr>
    <tr class="header">
        <td>
            <table> <tbody>
                <tr class="header">
                    <td> <u> February </u> </td>
                    <td>bar</td>
                </tr>
            </tbody> </table>
        </td>
    </tr>
</tbody> </table>

I'm trying to FIND "January" and add background color to the parent , here's my code so far:

var thetr = document.getElementsByTagName('tr');
for (j = 0; j < thetr.length; j++) {
    var theTd1 = thetr[j].getElementsByTagName('td');
    for (k = 0; k < theTd1.length; k++) {
        var theTd2 = theTd1[l].getElementsByTagName('td');
        for (m = 0; m < theTd2.length; k++) {
            if (theTd2[j].innerHtml == "January") {
                thetr[j].style.backgroundColor = "rgb(255, 195, 195)";
            }
        }
    }
}

Not getting anything... if I add an alert to show me the innerHtml that it's reading of each level I just get 'undefined'. How wrong is my method? Thank you in advance.


Solution

  • Several things:

    1. Always check the browser console for errors. There you would have seen things like:

      l is not defined

    2. Use querySelectorAll() (or use jQuery) to find nodes. You'll save yourself a ton of grief.
    3. Except when creating brand new nodes, using innerHtml in a Tampermonkey script is almost always a mistake and very brittle even if it works for a while. Your script, or the page, will break with the slightest change.
    4. If the page is AJAX-driven, static methods like that that will fail, irregardless.

    For a static page, this demo shows Vanilla.js for that row highlight:

    var headerCells = document.querySelectorAll ("tr.header > td > u");
    headerCells.forEach (uNode => {
        if (/January/i.test (uNode.textContent) ) {
            uNode.parentNode.parentNode.style.backgroundColor = "lime";
        }
    } );
    <table> <tbody>
        <tr class="header">
            <td>
                <table> <tbody>
                    <tr class="header">
                        <td> <u>January</u> </td>
                        <td>foo</td>
                    </tr>
                </tbody> </table>
            </td>
        </tr>
        <tr class="header">
            <td>
                <table> <tbody>
                    <tr class="header">
                        <td> <u>February</u> </td>
                        <td>bar</td>
                    </tr>
                </tbody> </table>
            </td>
        </tr>
    </tbody> </table>



    Or, in jQuery, the code is as simple as:

    $("tr.header > td > u:contains(January)").closest ("tr").css ("background", "lime");
    



    For either a static page or an AJAX-driven page, here is a complete Tampermonkey script that works:

    // ==UserScript==
    // @name     _Highlight January
    // @match    *://YOUR_SERVER.COM/YOUR_PATH/*
    // @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
    // @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant    GM_addStyle
    // ==/UserScript==
    //- The @grant directives are needed to restore the proper sandbox.
    /* global $, waitForKeyElements */
    
    waitForKeyElements ("tr.header > td > u:contains(January)", justLimen);
    
    function justLimen (jNode) {
        jNode.closest ("tr").css ("background", "lime");
    }