最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to get all elements from querySelectorAll and use with addEventListener - Stack Overflow

programmeradmin0浏览0评论

I have a block. When I click on plus, 4 subblocks are created.I have to add when I click on any of the subblocks plus buton (rooms-guests-plus class) , they increase from 0 to 5 and when click minus button (rooms-guests-minus class) decrease the same way.

const room = document.querySelector('.room-guests-count');
const form = document.querySelector('.form-open');
const adultsChildren = document.querySelector('.adults-children');
const adultsChildrenWrapper = document.querySelector('.adults-children-wrapper');

const toggleRoom = () => {
  const addRoomButton = document.querySelector('#add-room');
  const removeRoomButton = document.querySelector('#remove-room');
  const countRoom = document.querySelector('.form-text');
 
  const addSection = () => {
    const wrapper = document.createElement("div"); 
    wrapper.className = "adults-children-wrapper"; 
    wrapper.innerHTML = adultsChildrenWrapper.innerHTML;                
    adultsChildren.appendChild(wrapper).querySelector(".room-count").innerText = countRoom.value;

  }
  const removeSection = () => {
    adultsChildren.lastChild.remove();
  }
  
  addRoomButton.onclick = () => {
    if(countRoom.value == 4) return;
    countRoom.value++;
    addSection();  
   }
  removeRoomButton.onclick = () => {
    if(countRoom.value == 1) return;
    countRoom.value--;
    removeSection();
  }
}
toggleRoom();
body {
  background:#000;
}
/*ROOM GUESTS COUNT*/
.room-guests-count {
	width: 32.2%;
	cursor: pointer;
	margin-right: 4%;
	background: #fff;
	float: left;
	height: 66px;
	margin-right: 149px;
}
.form-open {
	display: block;
	position: absolute;
	z-index: -1;
	top: 85px;
	background-color: #fff;
	height: auto;
	width: 348px;
}

.form-open:after {
	content: '';
	position: absolute;
	width: 0;
	height: 0;
	border-bottom: 10px solid #fff;
	border-left: 10px solid transparent;
	border-right: 10px solid transparent;
	right: 300px;
	top: -10px;
}
.room-guests-content {
	padding-top: 23px;
	padding-left: 15px;
}
.click_hidden_text {
	position: absolute;
	z-index: 1;
	left: 163px;
	top: 56px;
	opacity: 0.8;
}
.form-search {
	padding: 0;
	margin: 10px 10px 5px 10px;
	
}
.form-item {
	padding: 10px 5px;
	clear: both;
	height: 14px;
}
.edit-rooms {
	font-weight: normal;
	font-size: 13px;
	float: left;
	color: #000;
	margin-right: 5px;
}
.rooms-guests-plus, #add-room {
	float: right;
	color: #fff;
	background:#ccc;
	width: 24px;
	height: 24px;
	text-align: center;
	line-height: 24px;
	top: -6px;
	position: relative;
	font-size: 18px;
	cursor: pointer;
}
.form-text {
	text-align: center;
	width: 6%;
	width: 20px !important;
	text-decoration: center;
	float: right;
	border:0;
	padding: 0;
	height: auto;
	outline: 0;
	vertical-align: middle;
}
.textfield label {
	margin-right: 2.5px;
	display: inline;
	font-size: 13px;
}
.children-1 label {
	display: inline;
	font-size: 13px;
}
.rooms-guests-minus, #remove-room {
	float: right;
	color: #fff;
	background:#e7e7e7;
	width: 24px;
	height: 24px;
	text-align: center;
	line-height: 24px;
	top: -6px;
	position: relative;
	font-size: 18px;
	cursor:auto;
}
.adults-children {
	clear: both;
}
.rooms-id {
	line-height: 40px;
	float: left;
	padding:5px 0 0 15px;
	color: #000;
}
.already-min {
	float: right;
	margin: -16px 0px 2px 6px;
	padding: 0;
	background: #fff;
}
.already-min-search {
	float: right;
	margin: 5px 10px 5px 2px;
}
.adults-children-wrapper {
	clear: both;
}
.children-1 {
	padding: 10px 5px;
	clear: both;
	height: 14px;
}
.edit-children {
	font-weight: normal;
	font-size: 13px;
	float: left;
	color: #000;
	margin-right: 5px;
}
.textfield {
	clear: both;
	height: 14px;
	margin: 0;
	position: relative;
	margin-top: 32px;
}
<script src=".1.1/jquery.min.js"></script>
<div class="room-guests-count">
    <div class="room-guests-content">
      Adult
      <span>2</span>
      , Child 
      <span>0</span>
    </div>
</div>
<div class="form-open">
  <div class="form-search">
    <div class="form-item">
      <label class="edit-rooms">Amount of number</label>
      <div id="add-room">+</div>
      <input class="form-text" value="1">
      <div id="remove-room">-</div>
    </div>
  </div>
  <div class="adults-children">
    <div class="adults-children-wrapper">
      <div class="rooms-id">Number <span class="room-count">1</span>:</div>
      <div class="already-min-search">
        <div class="children-1">
          <label for="edit-children">Child</label>
          <div class="rooms-guests-plus">+</div>
          <input type="text" value="0" class="form-text">
          <div class="rooms-guests-minus">-</div>
        </div>
      </div>
      <div class="already-min">
        <div class="textfield">
          <label for="edit">Adult</label>
          <div class="rooms-guests-plus">+</div>
          <input type="text" value="0"  class="form-text">
          <div class="rooms-guests-minus">-</div>
        </div>
      </div>
    </div>
  </div>
</div>

I have a block. When I click on plus, 4 subblocks are created.I have to add when I click on any of the subblocks plus buton (rooms-guests-plus class) , they increase from 0 to 5 and when click minus button (rooms-guests-minus class) decrease the same way.

const room = document.querySelector('.room-guests-count');
const form = document.querySelector('.form-open');
const adultsChildren = document.querySelector('.adults-children');
const adultsChildrenWrapper = document.querySelector('.adults-children-wrapper');

const toggleRoom = () => {
  const addRoomButton = document.querySelector('#add-room');
  const removeRoomButton = document.querySelector('#remove-room');
  const countRoom = document.querySelector('.form-text');
 
  const addSection = () => {
    const wrapper = document.createElement("div"); 
    wrapper.className = "adults-children-wrapper"; 
    wrapper.innerHTML = adultsChildrenWrapper.innerHTML;                
    adultsChildren.appendChild(wrapper).querySelector(".room-count").innerText = countRoom.value;

  }
  const removeSection = () => {
    adultsChildren.lastChild.remove();
  }
  
  addRoomButton.onclick = () => {
    if(countRoom.value == 4) return;
    countRoom.value++;
    addSection();  
   }
  removeRoomButton.onclick = () => {
    if(countRoom.value == 1) return;
    countRoom.value--;
    removeSection();
  }
}
toggleRoom();
body {
  background:#000;
}
/*ROOM GUESTS COUNT*/
.room-guests-count {
	width: 32.2%;
	cursor: pointer;
	margin-right: 4%;
	background: #fff;
	float: left;
	height: 66px;
	margin-right: 149px;
}
.form-open {
	display: block;
	position: absolute;
	z-index: -1;
	top: 85px;
	background-color: #fff;
	height: auto;
	width: 348px;
}

.form-open:after {
	content: '';
	position: absolute;
	width: 0;
	height: 0;
	border-bottom: 10px solid #fff;
	border-left: 10px solid transparent;
	border-right: 10px solid transparent;
	right: 300px;
	top: -10px;
}
.room-guests-content {
	padding-top: 23px;
	padding-left: 15px;
}
.click_hidden_text {
	position: absolute;
	z-index: 1;
	left: 163px;
	top: 56px;
	opacity: 0.8;
}
.form-search {
	padding: 0;
	margin: 10px 10px 5px 10px;
	
}
.form-item {
	padding: 10px 5px;
	clear: both;
	height: 14px;
}
.edit-rooms {
	font-weight: normal;
	font-size: 13px;
	float: left;
	color: #000;
	margin-right: 5px;
}
.rooms-guests-plus, #add-room {
	float: right;
	color: #fff;
	background:#ccc;
	width: 24px;
	height: 24px;
	text-align: center;
	line-height: 24px;
	top: -6px;
	position: relative;
	font-size: 18px;
	cursor: pointer;
}
.form-text {
	text-align: center;
	width: 6%;
	width: 20px !important;
	text-decoration: center;
	float: right;
	border:0;
	padding: 0;
	height: auto;
	outline: 0;
	vertical-align: middle;
}
.textfield label {
	margin-right: 2.5px;
	display: inline;
	font-size: 13px;
}
.children-1 label {
	display: inline;
	font-size: 13px;
}
.rooms-guests-minus, #remove-room {
	float: right;
	color: #fff;
	background:#e7e7e7;
	width: 24px;
	height: 24px;
	text-align: center;
	line-height: 24px;
	top: -6px;
	position: relative;
	font-size: 18px;
	cursor:auto;
}
.adults-children {
	clear: both;
}
.rooms-id {
	line-height: 40px;
	float: left;
	padding:5px 0 0 15px;
	color: #000;
}
.already-min {
	float: right;
	margin: -16px 0px 2px 6px;
	padding: 0;
	background: #fff;
}
.already-min-search {
	float: right;
	margin: 5px 10px 5px 2px;
}
.adults-children-wrapper {
	clear: both;
}
.children-1 {
	padding: 10px 5px;
	clear: both;
	height: 14px;
}
.edit-children {
	font-weight: normal;
	font-size: 13px;
	float: left;
	color: #000;
	margin-right: 5px;
}
.textfield {
	clear: both;
	height: 14px;
	margin: 0;
	position: relative;
	margin-top: 32px;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="room-guests-count">
    <div class="room-guests-content">
      Adult
      <span>2</span>
      , Child 
      <span>0</span>
    </div>
</div>
<div class="form-open">
  <div class="form-search">
    <div class="form-item">
      <label class="edit-rooms">Amount of number</label>
      <div id="add-room">+</div>
      <input class="form-text" value="1">
      <div id="remove-room">-</div>
    </div>
  </div>
  <div class="adults-children">
    <div class="adults-children-wrapper">
      <div class="rooms-id">Number <span class="room-count">1</span>:</div>
      <div class="already-min-search">
        <div class="children-1">
          <label for="edit-children">Child</label>
          <div class="rooms-guests-plus">+</div>
          <input type="text" value="0" class="form-text">
          <div class="rooms-guests-minus">-</div>
        </div>
      </div>
      <div class="already-min">
        <div class="textfield">
          <label for="edit">Adult</label>
          <div class="rooms-guests-plus">+</div>
          <input type="text" value="0"  class="form-text">
          <div class="rooms-guests-minus">-</div>
        </div>
      </div>
    </div>
  </div>
</div>

I wrote the if block in addSection function which the loop goes through all the elements (classes .rooms-child-plus) it works but the loop shows the error Can not read property 'addEventListener' of undefined.

if (adultsChildren.appendChild(wrapper)) {
    for(let i = 0;i < 4;i++){
      var roomsChildPlus = document.querySelectorAll(".rooms-child-plus");
      roomsChildPlus[i].addEventListener("click", function(){
        alert("hi");
      })
    }  
  }

The question is why such an error is output and on the correct path I am? and HOW to take all the elements with querySelectorAll and then use the addEventListener as an array also in the same way

Share Improve this question asked Jan 9, 2018 at 14:40 RandallRandall 2,8686 gold badges42 silver badges75 bronze badges 5
  • You have to parse the collection (NodeList) that querySelectorAll returns, and assign the event listener to each element individually. – Reinstate Monica Cellio Commented Jan 9, 2018 at 14:42
  • @Archer yup thank u.Already did.I use Array.from change nodelist to array but this didn't work. – Randall Commented Jan 9, 2018 at 14:43
  • ... or just spare yourself the hassle of having to loop through a set of elements to attach an event handler to each one individually altogether ... and use event delegation instead. – C3roe Commented Jan 9, 2018 at 14:45
  • I think this is simple flow --> querySelectorAll will return array then using for loop add event listener to each element. – Tushar Acharekar Commented Jan 9, 2018 at 14:45
  • I think you're getting a bit mixed up. You create a for loop and then inside that you create a node list using querySelectorAll(), and then use the loop value to index it. That makes no sense. Create the node list then create the loop and access the node list elements inside that loop. – Reinstate Monica Cellio Commented Jan 9, 2018 at 14:49
Add a ment  | 

2 Answers 2

Reset to default 5

You should loop through your roomsChildPlus instead of a hard coded length of 4.

var roomsChildPlus = document.querySelectorAll(".rooms-child-plus");

for(let j=0; j<roomsChildPlus.length; j++){
    roomsChildPlus[j].addEventListener("click", function(){
        alert("hi");
    });
}

Try like this:

document.querySelectorAll('.rooms-child-plus').forEach(el => 
     el.addEventListener('click',()=> {
      alert('hi');
      //or your action
}))

There are a better way, to do this: use event delegation good example, you will have only one event listener on many DOM elements.

document.addEventListener('click',(event) => {
    if(event.target.classList.contain('.rooms-child-plus')){
        //do something :)
    }
})
发布评论

评论列表(0)

  1. 暂无评论