简体   繁体   中英

setTimeout does not work inside eventlistener

I am trying to code a slider which should fade in an image if I click on a button.

 function showelementOnclick(selectorToID, firstShowingElenment, milliseconds) { var childElements = $(selectorToID).children(); var a = childElements.find("button"); for (var i = 0; i < a.length; i += 2) { a.eq(i).click(function() { childElements.eq(firstShowingElenment).css("display", "none"); firstShowingElenment--; console.log("first : " + firstShowingElenment) if (firstShowingElenment == -1) { firstShowingElenment = 2; } childElements.eq(firstShowingElenment).fadeIn(1000) console.log("Bin ich hier?") setTimeout(function() { console.log("hi") }, 5000) }) } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="slider"> <div class="slide first"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 1</button> <button>Vorwärts 1</button> </div> <div class="slide second"> <img src="Bilder/image.jpg" alt="" />--> <button>Rückwärts 2</button> <button>Vorwärts 2</button> </div> <div class="slide third"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 3</button> <button>Vorwärts 3</button> </div> </div>

This is my code, the fade in functionality does work, but setTimeout does not work properly. My goal is that, if a user clicks on the button that should display an image and if he wants to click twice he has to wait 5 seconds. Sorry for my bad english.

I replaced the JavaScript you provided with an alternative solution that I think should work for the functionality you described.

You can wrap the setTimeout in a Promise constructor and await it's completion. Simply disable the button prior to calling setTimeout and re-enable it once the timeout is done.

Using event delegation is a simpler way to handle event management than looping over each and every button element. The basic idea is to have a single event listener placed on the parent element in the DOM hierarchy and then inspect the event argument passed to the handler when the event occurs. This keeps code cleaner that having a unique handler setup for each and every button on the page. Below is an example:

 const sliderEl = document.querySelector('#slider'); const TIMEOUT_DURATION = 5000; sliderEl.addEventListener('click', async event => { if (event.target.tagName === 'BUTTON') { event.target.disabled = true; await new Promise((resolve, reject) => { setTimeout(resolve, TIMEOUT_DURATION); }); event.target.disabled = false; } });
 <div id="slider"> <div class="slide first"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 1</button> <button>Vorwärts 1</button> </div> <div class="slide second"> <img src="Bilder/image.jpg" alt="" />--> <button>Rückwärts 2</button> <button>Vorwärts 2</button> </div> <div class="slide third"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 3</button> <button>Vorwärts 3</button> </div> </div>

If this isn't what you're trying to achieve, I can re-read the question and amend my answer.

This should work on IE without having to use polyfills:

 const sliderEl = document.querySelector('#slider'); const TIMEOUT_DURATION = 5000; sliderEl.addEventListener('click', function(event) { if (event.target.tagName === 'BUTTON') { event.target.disabled = true; setTimeout(function() { event.target.disabled = false; }, TIMEOUT_DURATION); } });
 <div id="slider"> <div class="slide first"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 1</button> <button>Vorwärts 1</button> </div> <div class="slide second"> <img src="Bilder/image.jpg" alt="" />--> <button>Rückwärts 2</button> <button>Vorwärts 2</button> </div> <div class="slide third"> <img src="Bilder/Download.jpg" alt="" />--> <button>Rückwärts 3</button> <button>Vorwärts 3</button> </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