user10870573
user10870573

Reputation:

can't console log the div I click on

I'm making a connect four game and right now I just want the console log the div that's being clicked on the board. But for some reason the div that's being logged isn't the one that's clicked on.The div that's logged is always at the bottom of the board? Can someone please help me understand why this is happening. Thanks:)

const board = document.querySelectorAll(".slot");

for(let i = 0; i < board.length; i++) {
	board[i].addEventListener('click', dropChip);
}

function dropChip() {
	console.log(this);
}
/** {
	border: 1px solid red;
}*/

*,
*:before,
*:after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  justify-content: flex-end;
  min-height: 100vh;
  background-color: #e6e9ef;
  flex-direction: column;
}

.board-wrapper {
  /*display: flex;*/
  margin: 0 auto;
  padding-top: 100px;
  position: relative;
  overflow: hidden;
}

.board {
  display: flex;
  background-color: #00c;
  flex-wrap: wrap;
  max-width: 706px;
  padding: 3px;
  /*margin: auto;*/
}

.board>div {
  width: 100px;
  height: 100px;
  background-color: blue;
  border: 3px solid #00c;
  cursor: pointer;
  position: relative;
}

.board>div:after {
  content: "";
  position: absolute;
  z-index: 99;
  left: 0;
  right: 0;
  top: -999em;
  bottom: -999em;
  transition: all .5s ease;
  background-color: transparent;
}

.board>div:hover:after {
  background-color: #00c;
}

.board>div.counter {
  /*display: block;
	padding: 0;*/
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: auto;
  height: 100px;
  border: none;
  background-color: #e6e9ef;
  z-index: 100;
}

.board>div.counter:after {
  /*content: "";*/
  /*display: block;*/
  /*padding: 0;*/
  height: 80px;
  width: 80px;
  background-color: red;
  top: 0;
  /*left: 0;
	right: auto;*/
  border-radius: 50%;
  transition: transform .5s ease, opacity .2s ease;
  /*transform: translateX(0);*/
  z-index: 100;
  opacity: 0;
}

.board>div.counter:before {
  content: "";
  display: block;
  padding: 0;
  position: absolute;
  top: 15px;
  left: 15px;
  right: auto;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  background-color: red;
  box-shadow: inset 0px 0px 25px #cc0000;
  z-index: 101;
  transition: transform .5s ease, opacity .2s ease;
  /*transform: translateX(0);*/
  opacity: 0;
}

.board>div:nth-of-type(7n+1):hover~.counter:after {
  transform: translateX(14px);
  opacity: 1;
}

.board>div:nth-of-type(7n+2):hover~.counter:after {
  transform: translateX(114px);
  opacity: 1;
}

.board>div:nth-of-type(7n+3):hover~.counter:after {
  transform: translateX(214px);
  opacity: 1;
}

.board>div:nth-of-type(7n+4):hover~.counter:after {
  transform: translateX(314px);
  opacity: 1;
}

.board>div:nth-of-type(7n+5):hover~.counter:after {
  transform: translateX(414px);
  opacity: 1;
}

.board>div:nth-of-type(7n+6):hover~.counter:after {
  transform: translateX(514px);
  opacity: 1;
}

.board>div:nth-of-type(7n+7):hover~.counter:after {
  transform: translateX(614px);
  opacity: 1;
}

.board>div:nth-of-type(7n+1):hover~.counter:before {
  transform: translateX(14px);
  opacity: 1;
}

.board>div:nth-of-type(7n+2):hover~.counter:before {
  transform: translateX(114px);
  opacity: 1;
}

.board>div:nth-of-type(7n+3):hover~.counter:before {
  transform: translateX(214px);
  opacity: 1;
}

.board>div:nth-of-type(7n+4):hover~.counter:before {
  transform: translateX(314px);
  opacity: 1;
}

.board>div:nth-of-type(7n+5):hover~.counter:before {
  transform: translateX(414px);
  opacity: 1;
}

.board>div:nth-of-type(7n+6):hover~.counter:before {
  transform: translateX(514px);
  opacity: 1;
}

.board>div:nth-of-type(7n+7):hover~.counter:before {
  transform: translateX(614px);
  opacity: 1;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Connect Four</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="board-wrapper">
    <div class="board">
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="counter"></div>
    </div>
  </div>
  <script src="script.js"></script>
</body>

</html>

Upvotes: 1

Views: 956

Answers (3)

hackape
hackape

Reputation: 19967

Normally I don't use this in event listener. I find it very confusing, should be considered an antipattern. You can use evt.target, way more clear.

const board = document.querySelectorAll(".slot");

for(let i = 0; i < board.length; i++) {
    board[i].addEventListener('click', dropChip);
}

function dropChip(evt) {
    console.log(evt.target);
}

As to an explanation, I'm confused too. I think your code should work...


Edit: So it turns out to be a css problem (see Maaz's answer), I didn't look into the stylesheet, miss that part. OP's script is valid, it does work.

Upvotes: 1

Abana Clara
Abana Clara

Reputation: 4650

It's been found out that the issue is actually the CSS, but I'm leaving this here for extra infomation.

The common approach would be to pass the event.target as an argument on the dropChip function

const board = document.querySelectorAll(".slot");

for(let i = 0; i < board.length; i++) {
    board[i].addEventListener('click', function(evt){ dropChip(evt.target) });
}


function dropChip(div) {
    console.log(div);
}

Event listeners will always automatically supply an event object when executing the callback, which is why we added an evt parameter on our anonymous function.

You can also omit the anonymous function if you want to be straightforward

for(let i = 0; i < board.length; i++) {
    board[i].addEventListener('click', dropChip);
}


function dropChip(evt) {
    console.log(evt.target);
}

You can also pass the iterated item instead during the loop

for(let i = 0; i < board.length; i++) {
    board[i].addEventListener('click', function(evt){ dropChip(board[i]) });
}

Upvotes: 4

maazadeeb
maazadeeb

Reputation: 6112

Commenting out .board>div:after CSS rule solves the problem of the right this context. It's because all your slot divs are the same height. So the lower most divs in the DOM are positioned above the rest. Your JS is actually fine, it's the CSS that makes the divs so large that it looks like you're clicking on one, but the click is registered on something else much lower in the DOM.

const board = document.querySelectorAll(".slot");

for(let i = 0; i < board.length; i++) {
	board[i].addEventListener('click', dropChip);
}

function dropChip() {
	console.log(this);
}
/** {
	border: 1px solid red;
}*/

*,
*:before,
*:after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  justify-content: flex-end;
  min-height: 100vh;
  background-color: #e6e9ef;
  flex-direction: column;
}

.board-wrapper {
  /*display: flex;*/
  margin: 0 auto;
  padding-top: 100px;
  position: relative;
  overflow: hidden;
}

.board {
  display: flex;
  background-color: #00c;
  flex-wrap: wrap;
  max-width: 706px;
  padding: 3px;
  /*margin: auto;*/
}

.board>div {
  width: 100px;
  height: 100px;
  background-color: blue;
  border: 3px solid #00c;
  cursor: pointer;
  position: relative;
}

/* Commented out.
.board>div:after {
  content: "";
  position: absolute;
  z-index: 99;
  left: 0;
  right: 0;
  top: -999em;
  bottom: -999em;
  transition: all .5s ease;
  background-color: transparent;
}*/

.board>div:hover:after {
  background-color: #00c;
}

.board>div.counter {
  /*display: block;
	padding: 0;*/
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: auto;
  height: 100px;
  border: none;
  background-color: #e6e9ef;
  z-index: 100;
}

.board>div.counter:after {
  /*content: "";*/
  /*display: block;*/
  /*padding: 0;*/
  height: 80px;
  width: 80px;
  background-color: red;
  top: 0;
  /*left: 0;
	right: auto;*/
  border-radius: 50%;
  transition: transform .5s ease, opacity .2s ease;
  /*transform: translateX(0);*/
  z-index: 100;
  opacity: 0;
}

.board>div.counter:before {
  content: "";
  display: block;
  padding: 0;
  position: absolute;
  top: 15px;
  left: 15px;
  right: auto;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  background-color: red;
  box-shadow: inset 0px 0px 25px #cc0000;
  z-index: 101;
  transition: transform .5s ease, opacity .2s ease;
  /*transform: translateX(0);*/
  opacity: 0;
}

.board>div:nth-of-type(7n+1):hover~.counter:after {
  transform: translateX(14px);
  opacity: 1;
}

.board>div:nth-of-type(7n+2):hover~.counter:after {
  transform: translateX(114px);
  opacity: 1;
}

.board>div:nth-of-type(7n+3):hover~.counter:after {
  transform: translateX(214px);
  opacity: 1;
}

.board>div:nth-of-type(7n+4):hover~.counter:after {
  transform: translateX(314px);
  opacity: 1;
}

.board>div:nth-of-type(7n+5):hover~.counter:after {
  transform: translateX(414px);
  opacity: 1;
}

.board>div:nth-of-type(7n+6):hover~.counter:after {
  transform: translateX(514px);
  opacity: 1;
}

.board>div:nth-of-type(7n+7):hover~.counter:after {
  transform: translateX(614px);
  opacity: 1;
}

.board>div:nth-of-type(7n+1):hover~.counter:before {
  transform: translateX(14px);
  opacity: 1;
}

.board>div:nth-of-type(7n+2):hover~.counter:before {
  transform: translateX(114px);
  opacity: 1;
}

.board>div:nth-of-type(7n+3):hover~.counter:before {
  transform: translateX(214px);
  opacity: 1;
}

.board>div:nth-of-type(7n+4):hover~.counter:before {
  transform: translateX(314px);
  opacity: 1;
}

.board>div:nth-of-type(7n+5):hover~.counter:before {
  transform: translateX(414px);
  opacity: 1;
}

.board>div:nth-of-type(7n+6):hover~.counter:before {
  transform: translateX(514px);
  opacity: 1;
}

.board>div:nth-of-type(7n+7):hover~.counter:before {
  transform: translateX(614px);
  opacity: 1;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Connect Four</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="board-wrapper">
    <div class="board">
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="slot"></div>
      <div class="counter"></div>
    </div>
  </div>
  <script src="script.js"></script>
</body>

</html>

If the purpose of that rule is to highlight all the divs in a column, you might need a different approach.

Upvotes: 2

Related Questions