Home > Net >  I want to use the word 'an' before a tagName that begins with any of the characters in an
I want to use the word 'an' before a tagName that begins with any of the characters in an

Time:09-02

I recently came across the "event.currentTarget" and the "event.target" features in JavaScript. So I decided to write a little program that differentiates between the two. The initial way I wrote the program was okay until I thought about improving it a bit with an array that is mainly comprised of vowel alphabets, and an if statement to check whether the first alphabet of the node or tag name begins with any of the array items.

――――――――――――― The annoying little problem ―――――――――――――

In the first condition of the if statement, I basically said: if an HTML element begins with any of these alphabets in the array, let the word, "an", come before it.

In spite of the fact that the above statement comes first, the second statement is the one that executes, which says: You clicked on "a" EM element, instead of the word "an" (you know, since it is grammatically correct to say: "an EM element" instead of "a EM element").

const grandParent = document.querySelector('main#grand-parent')
const parent = document.querySelector('section#parent')
const children = document.querySelector('div#children')

const currentTargetOutput = document.querySelector('strong#currentTargetOutput')
const targetOutput = document.querySelector('strong#targetOutput')

function currentTargetClick(e) {
  currentTargetOutput.textContent = `You clicked on a ${e.currentTarget.tagName} element`;
}

const vowels = ['A', 'E', 'I', 'O', 'a', 'e', 'i', 'o']

function targetClick(e) {
  for (const vowel of vowels) {
    if (e.target.nodeName.startsWith(vowel)) {
      targetOutput.textContent = `You clicked on an ${e.target.nodeName} element`;
    } else {
      targetOutput.textContent = `You clicked on a ${e.target.nodeName} element`;
    }
  }
}


grandParent.addEventListener('click', currentTargetClick)
grandParent.addEventListener('click', targetClick)
body {
  font-family: 'Nirmala UI';
  background-color: #dddddd;
}

main#grand-parent {
  background-color: #0ff;
  width: 300px;
  height: 300px;
  display: grid;
  place-items: center;
  margin-left: auto;
  margin-right: auto;
}

section#parent {
  background-color: #f00;
  width: 250px;
  height: 250px;
  display: grid;
  place-items: center;
}

div#children {
  background-color: #0f0;
  color: #fff;
  width: 200px;
  height: 200px;
  text-align: center;
}

div#output {
  margin-top: 20px;
  margin-left: auto;
  margin-right: auto;
  width: fit-content;
}
<main id="grand-parent">
  <section id="parent">
    <div id="children">
      <h1>Hello</h1>
      <h3>World!</h3>
      <p>You</p>
      <strong>are welcome</strong>
      <em>again</em>
    </div>
  </section>
</main>
<div id="output">
  <strong id="currentTargetOutput"></strong>
  <br />
  <strong id="targetOutput"></strong>
</div>

Please help me solve this.

CodePudding user response:

Perhaps you're looping through each vowel asking the system to output yes or no for each one - when you'd rather just find out if the first letter is a vowel. I was able to get it working by ditching the loop and just going with this comparison

if (vowels.includes(e.target.nodeName.substring(0,1))) {

const grandParent = document.querySelector('main#grand-parent')
const parent = document.querySelector('section#parent')
const children = document.querySelector('div#children')

const currentTargetOutput = document.querySelector('strong#currentTargetOutput')
const targetOutput = document.querySelector('strong#targetOutput')

function currentTargetClick(e) {
  currentTargetOutput.textContent = `You clicked on a ${e.currentTarget.tagName} element`;
}

const vowels = ['A', 'E', 'I', 'O', 'a', 'e', 'i', 'o']

function targetClick(e) {
  if (vowels.includes(e.target.nodeName.substring(0, 1))) {
    targetOutput.textContent = `You clicked on an ${e.target.nodeName} element`;
  } else {
    targetOutput.textContent = `You clicked on a ${e.target.nodeName} element`;
  }

}


grandParent.addEventListener('click', currentTargetClick)
grandParent.addEventListener('click', targetClick)
body {
  font-family: 'Nirmala UI';
  background-color: #dddddd;
}

main#grand-parent {
  background-color: #0ff;
  width: 300px;
  height: 300px;
  display: grid;
  place-items: center;
  margin-left: auto;
  margin-right: auto;
}

section#parent {
  background-color: #f00;
  width: 250px;
  height: 250px;
  display: grid;
  place-items: center;
}

div#children {
  background-color: #0f0;
  color: #fff;
  width: 200px;
  height: 200px;
  text-align: center;
}

div#output {
  margin-top: 20px;
  margin-left: auto;
  margin-right: auto;
  width: fit-content;
}
<main id="grand-parent">
  <section id="parent">
    <div id="children">
      <h1>Hello</h1>
      <h3>World!</h3>
      <p>You</p>
      <strong>are welcome</strong>
      <em>again</em>
    </div>
  </section>
</main>
<div id="output">
  <strong id="currentTargetOutput"></strong>
  <br />
  <strong id="targetOutput"></strong>
</div>

CodePudding user response:

Well, this may seem a bit funny, if it is.

I spent over six hours trying to solve this question I posted about two hours ago, until I got a solution around now.

So I figured out a possible solution to this problem by removing the for loop and including this condition in the first if statement:

vowels.includes(e.target.nodeName[0])

This is simply saying that, if the vowels array has or includes any character which is the first letter of the name of the tagName or element clicked upon, include "an" before it.

const grandParent = document.querySelector('main#grand-parent')
const parent = document.querySelector('section#parent')
const children = document.querySelector('div#children')

const currentTargetOutput = document.querySelector('strong#currentTargetOutput')
const targetOutput = document.querySelector('strong#targetOutput')

function currentTargetClick(e) {
  currentTargetOutput.textContent = `You clicked on a ${e.currentTarget.tagName} element`;
}

const vowels = ['a', 'e', 'i', 'o', 'A', 'E', 'I', 'O']

function targetClick(e) {
  if (vowels.includes(e.target.nodeName[0])) {
    targetOutput.textContent = `You clicked on an ${e.target.nodeName} element`;
  } else {
    targetOutput.textContent = `You clicked on a ${e.target.nodeName} element`;
  }
}

grandParent.addEventListener('click', currentTargetClick)
grandParent.addEventListener('click', targetClick)
body {
  font-family: 'Nirmala UI';
  background-color: #dddddd;
}

main#grand-parent {
  background-color: #0ff;
  width: 300px;
  height: 300px;
  display: grid;
  place-items: center;
  margin-left: auto;
  margin-right: auto;
}

section#parent {
  background-color: #f00;
  width: 250px;
  height: 250px;
  display: grid;
  place-items: center;
}

div#children {
  background-color: #0f0;
  color: #fff;
  width: 200px;
  height: 200px;
  text-align: center;
}

div#output {
  margin-top: 20px;
  margin-left: auto;
  margin-right: auto;
  width: fit-content;
}
<main id="grand-parent">
  <section id="parent">
    <div id="children">
      <h1>Hello</h1>
      <h3>World!</h3>
      <p>You</p>
      <strong>are welcome</strong>
      <em>again</em>
    </div>
  </section>
</main>
<div id="output">
  <strong id="currentTargetOutput"></strong>
  <br />
  <strong id="targetOutput"></strong>
</div>

  • Related