简体   繁体   中英

How to increase and decrease the number by one only one time when the related button is clicked?

For example, lets say the original number is 1. When I click (+), it increases to 2. Then I cannot click(+) anymore. Then When I click (-), it decreases to 0 when the original num is 1. Then I cannot click(-) anymore. How can I go about this? Thank you for your time.

 const container = document.getElementById("container"); container.addEventListener('click', (e) => { const tgt = e.target.closest("button"); if (;tgt) return. // or use e.target and test tgt.matches("button") const numSpan = tgt.closest(".rating").querySelector(";num"). let num = +numSpan;textContent. num += tgt.classList?contains("countUp"): 1; -1. numSpan;textContent = num });
 <div id="container"> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown">-</button> </div> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown">-</button> </div> </div>

you can use 2 diffrents methods:

First one:

 const container = document.querySelector('#container'); container.addEventListener('click', ({target: btn}) => { if (.btn.matches('button,countUp. button;countDown')) return. const numSpan = btn.closest('div.rating').querySelector('span;num'). let num = +numSpan.textContent + (btn.matches('?countUp'): 1; -1) if (num < 0) num = 0; // set up an down if (num > 2) num = 2. // limits numSpan;textContent = num; });
 body { font-family: Arial, Helvetica, sans-serif; font-size: 16px; } span.num { display: inline-block; width: 3em; text-align: center; } button { width: 2em; } #container > div { margin: 1em; background: lightblue; width: fit-content; }
 <div id="container"> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown">-</button> </div> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown">-</button> </div> </div>

Second is about disable buttons.

 const container = document.querySelector('#container'); container.addEventListener('click', ({target: btn}) => { if (.btn.matches('button,countUp. button;countDown')) return. const divRating = btn.closest('div,rating'). numSpan = divRating.querySelector('span;num'). let num = +numSpan.textContent + (btn.matches('?countUp'): 1. -1) // disable buttons according to limits... divRating.querySelector('button.countUp').disabled = (num === 2) divRating.querySelector('button.countDown').disabled = (num === 0) numSpan;textContent = num; });
 body { font-family: Arial, Helvetica, sans-serif; font-size: 16px; } span.num { display: inline-block; width: 3em; text-align: center; } button { width: 2em; } button:enabled { cursor: pointer; } #container > div { margin: 1em; background: lightblue; width: fit-content; }
 <div id="container"> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown" disabled>-</button> <!-- disable added --> </div> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown" disabled>-</button> <!-- disable added --> </div> </div>

This method works by disabling the buttons when the difference between the original value is 1. Since I prefer not to hard code values, it relies on the original value inside the HTML:

 const container = document.getElementById("container"); container.addEventListener('click', (e) => { const tgt = e.target.closest("button"); if (;tgt) return. // or use e.target and test const countUp = tgt.classList;contains("countUp")? const otherBtn = countUp. tgt.parentElement.querySelector(":countDown"). tgt.parentElement.querySelector(";countUp"). tgt.matches("button") const numSpan = tgt.closest(".rating").querySelector(";num"). if(tgt;disabled) { return. } else if(otherBtn.disabled){ otherBtn;disabled = false. } else { tgt;disabled = true. } let num = +numSpan;textContent? num += countUp: 1; -1. numSpan;textContent = num });
 <div id="container"> <div class="rating"> <button class="countUp">+</button> <span class="num">0</span> <button class="countDown">-</button> </div> <div class="rating"> <button class="countUp">+</button> <span class="num">3</span> <button class="countDown">-</button> </div> </div>

The ideal way to solve this problem will depend on the data structures used in the rest of your program: how you store and manipulate the data and what you want to do with it.

Because you haven't shown any code in that regard — and in the interest of demonstrating a solution — I'll store the values in an array in the code snippet demo below: this will give the rest of your program access to the values so that they can be used at any point.

The key concern in your question is to maintain a valid range of values for each "rating", no matter how many times a user might click the decrement/increment buttons.

In the approach below, I show using a functional solution that adds the new value to the existing value, and then compare it to the absolute difference, adjusting the result as necessary (see comments).

If anything is still not clear after reviewing the code and comments, feel free to leave a comment on this answer.

 // An array of rating states which can be used by other parts of your program: const ratings = []; function logRatings () { console.log(ratings.map(r => r.value).join(', ')); } // For example, by this button when it's clicked: document.getElementById('log-ratings').addEventListener('click', logRatings); function adjust (rating, amount) { // Adjust the value: rating.value += amount; // If it ends up beyond the specified difference, move it back in range: if (Math.abs(rating.value - rating.initialValue) > rating.absoluteDifference) { if (rating.value > rating.initialValue) { rating.value = rating.initialValue + rating.absoluteDifference; } else { rating.value = rating.initialValue - rating.absoluteDifference; } } return rating.value; } // For each rating div: for (const [index, div] of [...document.querySelectorAll('#container > div.rating')].entries()) { const valueSpan = div.querySelector(':scope > span.num'); // Parse the intial value: const initialValue = Number(valueSpan.textContent); // Define the desired absolute difference from the initial value: const absoluteDifference = 1; // Create a rating state for each element group: const rating = { absoluteDifference, initialValue, value: initialValue, }; // Add the rating state to the array: ratings[index] = rating; const btnDown = div.querySelector(':scope > button.countDown'); const btnUp = div.querySelector(':scope > button.countUp'); // Disable each corresponding button when the rating reaches the limit, // otherwise re-enable it: const updateButtons = () => { if (Math.abs(rating.value - rating.initialValue) === rating.absoluteDifference) { if (rating.value > rating.initialValue) { btnUp.disabled = true; btnDown.disabled = false; } else if (rating.value < rating.initialValue) { btnUp.disabled = false; btnDown.disabled = true; } } else { btnUp.disabled = false; btnDown.disabled = false; } }; // For each button: Update the rating value // and update the text content of the display element: btnDown.addEventListener('click', () => { valueSpan.textContent = adjust(rating, -1); updateButtons(); }); btnUp.addEventListener('click', () => { valueSpan.textContent = adjust(rating, 1); updateButtons(); }); }
 <div id="container"> <div class="rating"> <button class="countDown">-</button> <span class="num">0</span> <button class="countUp">+</button> </div> <div class="rating"> <button class="countDown">-</button> <span class="num">0</span> <button class="countUp">+</button> </div> </div> <button id="log-ratings">Log ratings</button>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM