Home > Software design >  It is necessary to go over an element at least once to execute JS code
It is necessary to go over an element at least once to execute JS code

Time:02-12

I am doing a Connect Four in HTML CSS JS and I want to display a token at the top of the grid if you are hover the grid, align to the column so I put a listener to the grid. But to display this I need to go over all the elements at least one time and then after it will display as expected.

Here's the snippet, I'm sorry for the low quality code

quiJoue = 0;

$('#grille').on("mouseover", function(e) {
  let couleur = quiJoue % 2 === 0 ? "Jaune" : "Rouge";
  let classes = e.target.classList;
  if (classes.contains("top") && classes.contains("pion")) {
    let courant = e.target;
    $(courant).css("background", 'yellow').css("background-size", "contain");
  } else if (classes.contains('pion')) {
    let courant = (e.target);
    let colonne = (e.target.parentNode.classList[2]).split("-")[1];
    $('.cell.row-top.colonne-'   colonne).children().css("background", 'yellow').css("background-size", "contain")
    $(courant).hover(function() {
      $('.cell.row-top.colonne-'   colonne).children().addClass('top_hover');
    }, function() {
      $('.cell.row-top.colonne-'   colonne).children().removeClass('top_hover')
    });
  } else if (classes.contains('cell')) {
    let colonne = (e.target.classList[2]).split("-")[1];
    let courant = (e.target);
    $('.cell.row-top.colonne-'   colonne).children().css("background", 'yellow').css("background-size", "contain")
    $(courant).hover(function() {
      $('.cell.row-top.colonne-'   colonne).children().addClass('top_hover');
    }, function() {
      $('.cell.row-top.colonne-'   colonne).children().removeClass('top_hover')
    });

  }
});
.game-board {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  height: 700px;
  margin: 10px 0 25px;
  width: 700px;
}

.cell {
  align-items: center;
  background: #4370F1;
  display: flex;
  height: 100px;
  justify-content: center;
  width: 100px;
}

.pion {
  background: white;
  background-size: contain;
  border-radius: 50%;
  border: 3px solid black;
  height: 75px;
  width: 75px;
}

.top {
  transition: opacity 50ms linear;
  opacity: 0;
  border: 0;
}

.top:hover {
  transition: opacity 50ms linear;
  background-size: contain;
  opacity: 1;
}

.top_hover {
  transition: opacity 50ms linear;
  background-size: contain;
  opacity: 1;
}

.cell:not(.row-top).red::after {
  background: red;
}

.cell:not(.row-top).yellow::after {
  background: yellow;
}

.cell:not(.row-top).red.win {
  background: red;
}

.cell:not(.row-top).yellow.win {
  background: yellow;
}

.cell.row-top {
  background: rgba(255, 255, 255, 0);
}

.cell.row-top::after {
  border: none;
}

.cell.row-top.red::after {
  background: red;
  border: 3px solid black;
}

.cell.row-top.yellow::after {
  background: yellow;
  border: 3px solid black;
}

.left-border {
  border-left: 3px solid black;
}

.top-border {
  border-top: 3px solid black;
}

.right-border {
  border-right: 3px solid black;
}

.bottom-border {
  border-bottom: 3px solid black;
}

.left-border.top-border {
  border-radius: 10px 0 0 0;
}

.right-border.top-border {
  border-radius: 0 10px 0 0;
}

.right-border.bottom-border {
  border-radius: 0 0 10px 0;
}

.left-border.bottom-border {
  border-radius: 0 0 0 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div  id="grille" style="grid-template-columns: repeat(7, 1fr);">
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: rgba(0, 0, 0, 0) url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
  </div>
</div>

CodePudding user response:

I will try to demonstrate the issue in some bullet points, so let me know if they are not clear enough.

  • After the compiling process ends and your page load, there are no listeners attached to the game elements.
  • In the first hover iteration, your code will initialize the event listener dynamically but will not execute it.
  • After that, you have a listener attached to your element and will fire its callback function from now on.
  • So, for every hover event after that, your code will work as expected

SOLUTION

We need to attach the event listener to all game elements statically not dynamically. so here is the JS code we need.

    $(".pion").hover(function(e) {
      const colonne = (e.target.parentNode.classList[2]).split("-")[1];
      $('.cell.row-top.colonne-'   colonne).children().toggleClass('top_hover');
    })

It will select all elements with pion class and will attach them our hover event that toggles the class name of the related colonne number.

Note: I have hard-coded the background color of the token to yellow in the HTML snippet for all columns. you can remove it and handle the logic of Jaune and Rouge

<div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>

$(".pion").hover(function(e) {
  const colonne = (e.target.parentNode.classList[2]).split("-")[1];
  $('.cell.row-top.colonne-'   colonne).children().toggleClass('top_hover');
})
.game-board {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  height: 700px;
  margin: 10px 0 25px;
  width: 700px;
}

.cell {
  align-items: center;
  background: #4370F1;
  display: flex;
  height: 100px;
  justify-content: center;
  width: 100px;
}

.pion {
  background: white;
  background-size: contain;
  border-radius: 50%;
  border: 3px solid black;
  height: 75px;
  width: 75px;
}

.top {
  transition: opacity 50ms linear;
  opacity: 0;
  border: 0;
}

.top:hover {
  transition: opacity 50ms linear;
  background-size: contain;
  opacity: 1;
}

.top_hover {
  transition: opacity 50ms linear;
  background-size: contain;
  opacity: 1;
}

.cell:not(.row-top).red::after {
  background: red;
}

.cell:not(.row-top).yellow::after {
  background: yellow;
}

.cell:not(.row-top).red.win {
  background: red;
}

.cell:not(.row-top).yellow.win {
  background: yellow;
}

.cell.row-top {
  background: rgba(255, 255, 255, 0);
}

.cell.row-top::after {
  border: none;
}

.cell.row-top.red::after {
  background: red;
  border: 3px solid black;
}

.cell.row-top.yellow::after {
  background: yellow;
  border: 3px solid black;
}

.left-border {
  border-left: 3px solid black;
}

.top-border {
  border-top: 3px solid black;
}

.right-border {
  border-right: 3px solid black;
}

.bottom-border {
  border-bottom: 3px solid black;
}

.left-border.top-border {
  border-radius: 10px 0 0 0;
}

.right-border.top-border {
  border-radius: 0 10px 0 0;
}

.right-border.bottom-border {
  border-radius: 0 0 10px 0;
}

.left-border.bottom-border {
  border-radius: 0 0 0 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div  id="grille" style="grid-template-columns: repeat(7, 1fr);">
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div >
      <div  style="background: yellow url(&quot;../img/pionJaune.png&quot;) repeat scroll center center / contain;"></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
    <div  data-couleur="">
      <div ></div>
    </div>
  </div>
</div>

  • Related