0

I have a set of lists, and each block of the list has a data-id set. I hope to get the data-id of the clicked block when the block is clicked. However, I am not familiar with javascript yet, so I don’t know how to get it correctly. I hope you can help me, thank you.

let wrap = document.querySelector('.wrap');
let item = wrap.querySelectorAll('.notice_item');

for (let i = 0; i < item.length; i++) {
  item[i].onclick = function(e) {
    console.log(e.target.dataset.id)
  }
}
.wrap {
  display: flex;
  flex-direction: column;
}

.wrap li {
  padding: 16px;
}

.wrap li:hover {
  background-color: yellow;
}

.wrap li .info_title {
  font-size: 20px;
  color: #222;
}

.wrap li .info_main {
  font-size: 14px;
  color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
  <li>
    <a class="notice_item" href="javascript:;" data-id="111">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="javascript:;" data-id="222">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="javascript:;" data-id="333">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
</ul>
AWEI
  • 417
  • 3
  • 9
  • 1
    Log `e.target` to the console, and you will see that is likely not the element you think it was (for example when you click directly on the h3 or p content.) Replace it with `e.currentTarget`. – CBroe Jan 17 '23 at 08:38

4 Answers4

2

This situation is better suited for the use of event delegation.

By the way, don't use inline javascript: for hrefs (or inline handling for that matter).

document.addEventListener(`click`, handle);

function handle(evt) {
  const checkNotice = evt.target.closest(`.notice_item`);
  if (checkNotice) {
    console.clear();
    console.log(checkNotice.dataset.id);
  }
}
.wrap {
  display: flex;
  flex-direction: column;
}

.wrap li {
  padding: 16px;
}

.wrap li:hover {
  background-color: yellow;
}

.wrap li .info_title {
  font-size: 20px;
  color: #222;
}

.wrap li .info_main {
  font-size: 14px;
  color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
  <li>
    <a class="notice_item" href="#" data-id="111">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="#" data-id="222">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="#" data-id="333">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
</ul>
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • First of all thank you for providing a different solution! But I have a question why using event delegation in this case is better than using for with e.currentTarget.dataset.id recommended by others? – AWEI Jan 17 '23 at 15:47
  • HI @AWEI, it's better because you only need *one* function to handle event(s), no loops etc., and it's easy to determine where the event came from. Let's say you wanted to add handling for `p.info_main`: that can be included in the `handle` function (`if (evt.target.closest('.info_main') ...`). Event delegation can also be used for future (not yet existing) elements. – KooiInc Jan 17 '23 at 16:44
  • That’s how it is~ In other words, this approach allows more room for flexible modification, thank you – AWEI Jan 18 '23 at 00:47
1

I've modified a little your html removing the a tag. i've add the listener to every div with class .notice_content ang get it's data-id on click

let wrap = document.querySelectorAll('.notice_content');

wrap.forEach(item => {
  item.addEventListener("click", function(){
    console.log(item.dataset.id)
  })
 })
.wrap {
  display: flex;
  flex-direction: column;
}

.wrap li {
  padding: 16px;
}

.wrap li:hover {
  background-color: yellow;
}

.wrap li .info_title {
  font-size: 20px;
  color: #222;
}

.wrap li .info_main {
  font-size: 14px;
  color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
  <li>
      <div class="notice_content" data-id="111">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
  <li>
      <div class="notice_content"  data-id="222">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
  <li>
      <div class="notice_content" data-id="333">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
</ul>
Sfili_81
  • 2,377
  • 8
  • 27
  • 36
1

You were very close. Check the code below. hope this helps.

let wrap = document.querySelector('.wrap');
let item = wrap.querySelectorAll('.notice_item');

for (let i = 0; i < item.length; i++) {
  item[i].onclick = function(e) {
    console.log(e.currentTarget.dataset.id);
  }
}
.wrap {
  display: flex;
  flex-direction: column;
}

.wrap li {
  padding: 16px;
}

.wrap li:hover {
  background-color: yellow;
}

.wrap li .info_title {
  font-size: 20px;
  color: #222;
}

.wrap li .info_main {
  font-size: 14px;
  color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
  <li>
    <a class="notice_item" href="javascript:;" data-id="111">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="javascript:;" data-id="222">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
  <li>
    <a class="notice_item" href="javascript:;" data-id="333">
      <div class="notice_content">
        <h3 class="info_title">TITLE</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
    </a>
  </li>
</ul>
JShobbyist
  • 532
  • 3
  • 9
  • 23
1

Here is the jQuery solution:

  • access dataset.id with .data('id')
  • access any child element with .find(), such as .find('.info_title').text()

Note that often you do not need an ID in each list element because you can access what you need from the DOM. You can find a child element with .find('.someClass'), traverse one element up with .parent(), find an element several levels up with .closest('.someClass').

$(function() {
   $('.notice_content').click(function() {
     let id = $(this).data('id');
     let title = $(this).find('.info_title').text();
     console.log('click on:', { id, title });
   });
 });
.wrap {
  display: flex;
  flex-direction: column;
}
.wrap li {
  padding: 16px;
}
.wrap li:hover {
  background-color: yellow;
}
.wrap li .info_title {
  font-size: 20px;
  color: #222;
}
.wrap li .info_main {
  font-size: 14px;
  color: #222;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="wrap">
  <li>
      <div class="notice_content" data-id="111">
        <h3 class="info_title">TITLE 111</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
  <li>
      <div class="notice_content"  data-id="222">
        <h3 class="info_title">TITLE 222</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
  <li>
      <div class="notice_content" data-id="333">
        <h3 class="info_title">TITLE 333</h3>
        <p class="info_main">Lorem ipsum dolor sit amet, consectetur adipisicing elit. In labore assumenda perspiciatis illum quo corrupti, magnam ratione fuga omnis enim!</p>
      </div>
  </li>
</ul>
Peter Thoeny
  • 7,379
  • 1
  • 10
  • 20