Home > Net >  Reduce the Number of Functions for an A-to-Z set of Letters
Reduce the Number of Functions for an A-to-Z set of Letters

Time:12-06

https://prnt.sc/21vc411 As you can see on the link when i click one letter in left side or in right side, that letter should disappear and should go to the opposite side. For example, when i click "A" letter on the left it goes to right. I created one letter on each side, and as default the right one's display is 'none'. So when i click the one on the left the following function starts;

function myFunction() {
document.getElementById("aLetterLeftSide").style.display="none";
document.getElementById("aLetterRigtSide").style.display="inline-block";
}       

It works but i have to do it for every letter with different id's. So there is approximately 50 functions :( Is there a way to shorten it to less functions ? Thank you for your answers :)

CodePudding user response:

You are binding your functions to your elements using Element ids (MDN Webdocs Link). When you have a bunch of elements that need the same function, just bind them use Element ClassName (MDN Webdocs Link) instead.

In the following example, I simple have letters with class defined as letter-span, and then I set the onclick (MDN Webdocs Link) property iteratively...

var letterspans = document.getElementsByClassName("letter-span");

var onclickfunc = function(e) {
  if(this.style.float) {
    this.style.float = '';
  } else {
    this.style.float = 'right';
  }
};

for(i = 0; i < letterspans.length; i  ) {
  letterspans[i].onclick = onclickfunc;
}
<span data-letter="a" class="letter-span">A</span> | 
<span data-letter="b" class="letter-span">B</span> | 
<span data-letter="c" class="letter-span">C</span> | 
<span data-letter="d" class="letter-span">D</span> 
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Note

The above is a full, working, stand-alone demo (please note: Minimal Reproducible Code). In this case, I did if(this.style.float){ and this.style.float = ''; you may need a different condition and setter, perhaps, if(this.classList.contains('rightside')) {.., and this.classList.add('rightside') along with this.classList.remove('rightside'). I didn't do it this way, because, I wanted something fully reprocudible in a demo.

CodePudding user response:

Event delegation allows you to use a single event listener for an unlimited number of elements.

Add the event listener on a parent element that contains all of the elements you want to click:

document.querySelector(Parent).onclick = clickHandler;

In the clickHandler(event) use event.target to get the clicked element:

const clicked = event.target

Check to see if it's the correct element:

if (clicked.matches('.node')) {...

Get in the habit of using class instead of #id The example below allows you to move items from and to both containers.

const moveNode = event => {
  const clicked = event.target;
  const from = clicked.parentElement;
  const toB = document.querySelector('.B');
  const toA = document.querySelector('.A');

  if (clicked.matches('.node')) {
    const node = from.removeChild(clicked);

    if (from.matches('.A')) {
      toB.appendChild(node);
    } else {
      toA.appendChild(node);
    }
  } else {
    return false;
  }
}

const main = document.querySelector('main');

main.onclick = moveNode;
main {
  display: flex;
  justify-content: space-around;
}

section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 45vw;
  min-height: 20vh;
  border: 1px solid black;
}

.node {
  font-size: 3ch;
  border: 1px solid black;
  width: 3ch;
  height: 2ch;
  text-align: center;
  cursor: pointer;
}
<main>
  <section class='A'>
    <div class='node'>A</div>
    <div class='node'>B</div>
    <div class='node'>C</div>
    <div class='node'>D</div>
    <div class='node'>E</div>
    <div class='node'>F</div>
    <div class='node'>G</div>
  </section>

  <section class='B'></section>
</main>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related