Kunal Tanwar
Kunal Tanwar

Reputation: 1291

Why the if statement is not running in forEach function in Javascript?

I have been working on tooltips and for that I created a javascript function Tooltip() in which I selected all the DOM elements like const targets = document.querySelectorAll('*') and after selecting all the elements, I addedforEach function on targets variable and inside for each function I created an if statement in which I checked if an element contains the specific attribute I mentioned in requiredAttrs array but it is not working somehow! And I don't know where I'm doing wrong.

COMPLETE CODE

function Tooltip() {
      const requiredAttrs = ['data-tooltip', 'data-tooltip-position', 'data-tooltip-content'];
      const targets = document.querySelectorAll('*');

      targets.forEach((target, index) => {
            if (target.hasAttribute(requiredAttrs[index])) {
                  console.log('Y');
            } else {
                  console.log('No');
            }
      });
}

Tooltip();
<!DOCTYPE html>
<html dir="ltr" lang="en">
      <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <link rel="stylesheet" href="public/css/main.css" />
            <title>Pearl Framework</title>
      </head>
      <body class="vh-full grid-center">
            <style>
                  body {
                        background-color: #a1a1a1;
                  }

                  .box {
                        width: 100px;
                        height: 100px;
                        background-color: purple;
                  }
            </style>

            <div
                  class="box"
                  data-tooltip="true"
                  data-tooltip-position="top-center"
                  data-tooltip-content="Hello, World!"
            ></div>

            <script src="public/script/tooltip.js"></script>
      </body>
</html>

As you can see a <div class="box"></div> has all 3 attributes so if statement should run but instead else part is running.

Upvotes: 0

Views: 120

Answers (2)

tengbretson
tengbretson

Reputation: 169

The index of the targets array does not correspond to the index of the requiredAttrs array you are comparing against. You'll want something like this:

targets.forEach((target, index) => {
  const hasAttrs = requiredAttrs.every(attr => target.hasAttribute(attr));
  if (hasAttrs) {
    console.log('Y');
  } else {
    console.log('No');
  }
});

Edit:

This works because your call to querySelectorAll is capturing literally every element on the page and returning it as an array. In your forEach call you are then using the array index position of the current element we are inspecting for the presence of those attributes to check against the requiredAttrs. So likely by the time we are even iterating to the div that has the attributes you are interested in we are likely dealing with an index that is greater than the length of the requiredAttrs array, let alone the fact that we would only be checking for one of the attrs rather than all of them. My code takes the target node and calls the .every method on the requiredAttrs array to check that every single one of the required attrs is present on the target node.

While this solves the initial problem, I should note that this will likely have poor performance and is not the recommended way to find elements that have particular attributes. If you want a collection of elements that are all guaranteed to have the attributes in your array you can simply add them to your query, like this:

docmuent.querySelectorAll('*[data-tooltip][data-tooltip-position][data-tooltip-content]');

Upvotes: 3

karaken
karaken

Reputation: 94

at first, it's not correct to use index here, because it's index of targets array, and if you take a look to output of document.querySelectorAll('*') u can see, that it's also includes, html, head, and other tags,

in other words you are trying to access to requiredAttrs by index that exceed it's lenght

u have to wrap your if statement with for loop arround requiredAttrs

Upvotes: 0

Related Questions