1

***EDIT -- the issue appears to be in the way I'm trying to add a class (I tried changing some CSS for the class to test and it doesn't do anything)

I want to find an element in the DOM based on text, and add a class to it, so that I can manipulate it/its parent elements

This is the function I wrote to do this (before this I'm using a function from stackoverflow to walk through the DOM , and call my function to replace the matches- (the actual string values are not important right now) -- the HTML I'm modifying is the DOM.

var MATCH = ['word'];
var REPLACE = ['other'];


   function replaceText(textNode) {
    var badWord = textNode.nodeValue;
    var replaceWord = "";
    badWord.className = "filter";

    //Go through and match/replace strings equal to MATCH
    for (var i=0; i< MATCH.length; i++) {
        replaceWord = document.getElementsByClassName("filter").innerHTML;
        replaceWord = replaceWord.replace(new RegExp('\\b' + MATCH[i] + '\\b', 'g'), REPLACE[i]);
    }
    textNode.nodeValue = replaceWord;
}

It works when I just directly replace the text in the word like this below - but I want to access and modify from the class, so that I can change the parent elements/css

//working version without adding class
function hide(textNode) {
    var badWord = textNode.nodeValue;

    //Go through and match/replace strings equal to MATCH
    for (var i=0; i< MATCH.length; i++) {
        badWord = badWord.replace(new RegExp('\\b' + MATCH[i] + '\\b', 'g'), REPLACE[i]);
    }
    textNode.nodeValue = badWord;
}

function from stackoverflow post -

walk(document.body);

function walk(node) {

    var child, next;

    switch (node.nodeType) {
        case ELEMENT:  // Element
        case DOCUMENT:  // Document
        case DOCUMENT_FRAGMENT: // Document fragment
            child = node.firstChild;
            while (child) {
                next = child.nextSibling;
                walk(child);
                child = next;
            }
            break;

        case TEXT: // Text node
            replaceText(node);
            break;
    }
}
Community
  • 1
  • 1
user146303
  • 437
  • 1
  • 7
  • 20
  • You use addClass on a nodeValue, which will not work, try `textNode.className = 'filter';`. If there are multiple classes 'filter', you can use `document.getElementsByClassName('filter')` to get them all. For a complete answer, please update your post with the HTML you are trying to modify, the word(s) to be replaced and link to the stackoverflow post with the DOM parse function. – M4tini May 27 '16 at 17:02
  • @M4tini added the link - I'm modifying the current page - this is for a chrome extension – user146303 May 27 '16 at 17:25

1 Answers1

1

I changed your replaceText() function and tested it on this page. It replaces text and adds a filter class on the nodes with replaced text. This solution uses classList.add('filter') which is not supported in IE9 and earlier, but that's no issue since this code is for a Chrome extension.

function replaceText(textNode) {
    var nodeValue = textNode.nodeValue;
    for (var i=0; i < MATCH.length; i++) {
        if(-1 != nodeValue.indexOf(MATCH[i])) {
            nodeValue = nodeValue.replace(new RegExp(MATCH[i], 'g'), REPLACE[i]);
            textNode.parentNode.classList.add('filter');
        }
    }
    textNode.nodeValue = nodeValue;
}
M4tini
  • 447
  • 1
  • 6
  • 11
  • FYI - I had to change the case values in that `walk()` function to get it working, for example: `DOCUMENT_FRAGMENT` to `Node.DOCUMENT_FRAGMENT_NODE`. – M4tini May 27 '16 at 21:57