简体   繁体   中英

Restrict the scope of functions in JavaScript ( Slider Use Case )?

In the following script, the code works when there is a slider, but when the number of sliders on a page is more than one, the next sliders do not work.

How can this script be changed when we have more than one slider on the page so that each slider " Draggable Feature " works separately and does not overlap?

What changes are needed to make this code "Draggable feature" work separately for each slider?

How can I handle this with " querySelectorAll " and " forEach " ?

 const slider = document.querySelector('.items'); let isDown = false; let startX; let scrollLeft; slider.addEventListener('mousedown', (e) => { isDown = true; slider.classList.add('active'); startX = e.pageX - slider.offsetLeft; scrollLeft = slider.scrollLeft; }); slider.addEventListener('mouseleave', () => { isDown = false; slider.classList.remove('active'); }); slider.addEventListener('mouseup', () => { isDown = false; slider.classList.remove('active'); }); slider.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - slider.offsetLeft; const walk = (x - startX) * 3; //scroll-fast slider.scrollLeft = scrollLeft - walk; });
 .items, .items_1 { position: relative; width: 90%; background: green; overflow-x: scroll; overflow-y: hidden; white-space: nowrap; transition: all 0.2s; transform: scale(0.98); will-change: transform; user-select: none; cursor: pointer; margin: 2rem auto; border: 3px solid violet; } .item { display: inline-block; background: red; min-height: 50px; min-width: 150px; margin: .5rem; }
 <!DOCTYPE html> <html lang="en"> <head> <title>slider</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <script src="./script.js"></script> </body> </html>

How can I handle this with " querySelectorAll " and " forEach " ?

Just put your code that declares the state variables and attaches the event handlers to one slider into such a loop:

 const sliders = document.querySelectorAll('.items'); for (const slider of sliders) { let isDown = false; let startX; let scrollLeft; slider.addEventListener('mousedown', (e) => { isDown = true; slider.classList.add('active'); startX = e.pageX - slider.offsetLeft; scrollLeft = slider.scrollLeft; }); slider.addEventListener('mouseleave', () => { isDown = false; slider.classList.remove('active'); }); slider.addEventListener('mouseup', () => { isDown = false; slider.classList.remove('active'); }); slider.addEventListener('mousemove', (e) => { if (!isDown) return; e.preventDefault(); const x = e.pageX - slider.offsetLeft; const walk = (x - startX) * 3; //scroll-fast slider.scrollLeft = scrollLeft - walk; }); }
 .items { position: relative; width: 90%; background: green; overflow-x: scroll; overflow-y: hidden; white-space: nowrap; transition: all 0.2s; transform: scale(0.98); will-change: transform; user-select: none; cursor: pointer; margin: 2rem auto; border: 3px solid violet; } .items.active { border-color: blue; } .item { display: inline-block; background: red; min-height: 50px; min-width: 150px; margin: .5rem; }
 <!DOCTYPE html> <html lang="en"> <head> <title>slider</title> <link rel="stylesheet" href="./style.css"> </head> <body> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <div class="items"> <div class="item"></div> <div class="item"></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> <div class="item "></div> </div> <script src="./script.js"></script> </body> </html>

I guess that question for your issue. All what you need was wrap your code into a function and set an argument for each slider.

 const slider1 = document.querySelector('.items1'); const slider2 = document.querySelector('.items2'); const slider3 = document.querySelector('.items3'); let isDown = false; let startX; let scrollLeft; const sliderFunc = el => { el.addEventListener('mousedown', e => { isDown = true; el.classList.add('active'); startX = e.pageX - el.offsetLeft; scrollLeft = el.scrollLeft; }); el.addEventListener('mouseleave', () => { isDown = false; el.classList.remove('active'); }); el.addEventListener('mouseup', () => { isDown = false; el.classList.remove('active'); }); el.addEventListener('mousemove', e => { if (!isDown) return; e.preventDefault(); const x = e.pageX - el.offsetLeft; const walk = (x - startX) * 3; //scroll-fast el.scrollLeft = scrollLeft - walk; }); }; sliderFunc(slider1); sliderFunc(slider2); sliderFunc(slider3);
 .items1, .items2, .items3, .items_1 { position: relative; width: 90%; background: green; overflow-x: scroll; overflow-y: hidden; white-space: nowrap; transition: all 0.2s; transform: scale(0.98); will-change: transform; user-select: none; cursor: pointer; margin: 2rem auto; border: 3px solid violet; } .item { display: inline-block; background: red; min-height: 50px; min-width: 150px; margin: 0.5rem; }
 <div class="items1"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> <div class="items2"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> <div class="items3"> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div>

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