Home > Back-end >  How to target divs with other content using DOM
How to target divs with other content using DOM

Time:09-26

I have a bunch of divs with some text in them. I am trying to create a simple function that targets divs with a specific text and gives them a class. I also want to give the divs with other text a common class.

I have managed to target the divs with the specific texts, but I cant figure out how to target the divs with other texts.

This is the HTML

<h1>The divs</h1>

  <div>High</div>
  <div>Low</div>
  <div>Medium</div>

  <div>Hit 'em high</div>
  <div>Medium rare</div>

  <div>A funky name</div>

and this is the function

const divs = document.querySelectorAll('div');
function classChanger () {
    for (let i = 0; i < divs.length; i  ) {
        if (divs[i].textContent === 'High') {
            divs[i].classList.add('high');
        } if (divs[i].textContent === 'Medium') {
            divs[i].classList.add('medium');
        } if (divs[i].textContent === 'Low') {
            divs[i].classList.add('low');
        } if (divs[i].textContent === 'anything') {
            divs[i].classList.add('none');
        } 
    }
};

classChanger();

I have tried to use several more if statemets with !== 'High' and so on, but they just overwrite the previous code.

So I am just wondering, how do I target the last three divs and give them the class none? I have tried googling but I dont think im googling the right question, thats why I am asking here.

CodePudding user response:

You can add High, Medium, and Low to an array. As you loop over the elements check to see if array includes the text (and set the class to the lowercase version of the text), otherwise add a none class.

const divs = document.querySelectorAll('div');

const range = ['High', 'Medium', 'Low'];

function classChanger() {
  for (let i = 0; i < divs.length; i  ) {
    const text = divs[i].textContent;
    if (range.includes(text)) {
      divs[i].classList.add(text.toLowerCase());
    } else {
      divs[i].classList.add('none');
    }
  }
}

classChanger();
.high { color: red; }
.medium { color: orange; }
.low { color: yellow; }
.none { color: darkgray; }
<div>High</div>
<div>Low</div>
<div>Medium</div>

<div>Hit 'em high</div>
<div>Medium rare</div>

<div>A funky name</div>

CodePudding user response:

You Can use an else if statement like this:

const divs = document.querySelectorAll("div");
function classChanger() {
  for (let i = 0; i < divs.length; i  ) {
    if (divs[i].textContent === "High") {
      divs[i].classList.add("high");
    } else if (divs[i].textContent === "Medium") {
      divs[i].classList.add("medium");
    } else if (divs[i].textContent === "Low") {
      divs[i].classList.add("low");
    } else {
      divs[i].classList.add("none");
    }
  }
}

classChanger();

CodePudding user response:

If you want to target elements based on content, you first need to create a function for such purpose like:

function queryElementsWithFilter(selector, filterCallback) {
  if (typeof selector !== 'string') throw new TypeError('param 1 must be a string')
  if (typeof filterCallback !== 'function') throw new TypeError('param 2 must be a function')

  const nodes = [...document.querySelectorAll(selector)]
  return nodes.filter(filterCallback)
}

Now you can get the elements you want and do anything with them.

const textTokens = ['High', 'Medium', 'Low']

textTokens.forEach(textToken => {
  const divCollection = queryElementsWithFilter(
    'div',
    node => node.textContent === textToken
  )

  divCollection.forEach(div => div.classList.add(textToken.toLowerCase()))
})

const unmatchedNodes = queryElementsWithFilter(
    'div',
    node => !textTokens.includes(node.textContent)
)

unmatchedNodes.forEach(div => div.classList.add('none'))
  • Related