簡體   English   中英

SetTimeout和ScrollTop的奇怪行為

[英]Strange behavior with SetTimeout and ScrollTop

我不明白為什么我必須將scrollTop函數包裝在setTimeout 我知道在后台使用setTimeout會發生什么:將函數放在Callback隊列中(從Web API提供),並在調用堆棧中的所有代碼完成后執行。 但是,為什么在這種情況下,我沒有setTimeout就具有這種行為?

例如,選擇spainluxembourg (Ctrl +單擊),請停留在select器的底部。 使用兩個按鈕進行測試。 發生兩種不同的行為。

編輯1:編輯:刪除所有console.log ,如果沒有setTimeout仍然無法正常工作

編輯2:在第一個答案之后,我嘗試了@Murali Nepalli的代碼,但仍然無法正常工作。 您可以確切地看到發生了什么(我在Google Chrome上)

編輯3:僅出現在Chrome瀏覽器上,我的版本: 75.0.3770.142 (Build officiel) (64 bits) (cohort: Stable)

scrollTop不起作用

 $(function() { $('form').on('resetwithtimeout', function(e) { var $select = $(e.currentTarget).find('select'); $select.find('option') .filter(':selected').prop("selected", false).end() .filter(':first').prop("selected", true); setTimeout(function() { $select.scrollTop(0); }, 0); }); $('form').on('resetwithouttimeout', function(e) { var $select = $(e.currentTarget).find('select'); $select.find('option') .filter(':selected').prop("selected", false).end() .filter(':first').prop("selected", true); $select.scrollTop(0); }); $('#button1').on('click', function(e) { $('form').trigger('resetwithtimeout'); }) $('#button2').on('click', function(e) { $('form').trigger('resetwithouttimeout'); }) }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <body> <form> <select name="country" id="country-select" multiple size="5"> <option selected value="austria">Austria</option> <option value="belgium">Belgium</option> <option value="bulgaria">Bulgaria</option> <option value="croatia">Croatia</option> <option value="republic">Republic of Cyprus</option> <option value="czech">Czech Republic</option> <option value="denmark">Denmark</option> <option value="estonia">Estonia</option> <option value="finland">Finland</option> <option value="france">France</option> <option value="germany">Germany</option> <option value="greece">Greece</option> <option value="hungary">Hungary</option> <option value="ireland">Ireland</option> <option value="italy">Italy</option> <option value="latvia">Latvia</option> <option value="lithuania">Lithuania</option> <option value="luxembourg">Luxembourg</option> <option value="malta">Malta</option> <option value="netherlands">Netherlands</option> <option value="poland">Poland</option> <option value="portugal">Portugal</option> <option value="romania">Romania</option> <option value="slovakia">Slovakia</option> <option value="slovenia">Slovenia</option> <option value="spain">Spain</option> <option value="sweden">Sweden and the UK</option> </select> <button id="button1" type="button">Reset form with scroll inside setTimeout</button> <button id="button2" type="button">Reset form with scroll not inside a setTimeout</button> </form> </body> 

謝謝 !

您可以只更改“選擇”元素的選擇索引。 這會將滾動位置重置為頂部。 https://jsfiddle.net/hbL8tzma/

$('form').on('resetwithouttimeout', function(e) {
    var $select = $(e.currentTarget).find('select');
    $select[0].selectedIndex = 0;      
});

那是Chrome的錯誤。

無論出於何種原因,每次我們以編程方式更改<option>之一的選定屬性時,他們都嘗試在最后一個用戶選擇的<option>上調用scrollIntoView ,如以下代碼片段所示:

 var $select = $('select') .on('input', function() { console.log('try to scroll inside the select'); current = 0; this.scrollTop = 0; // move to top startSelect(); $select .find('.user-selected').removeClass('user-selected') .end().find(':selected').addClass('user-selected'); }) var $options = $select.find('option'); var current = 0; console.log('select any option'); // selects all the <option>s one by one function startSelect() { setTimeout(function() { $options.prop("selected", false) .get(current).selected = true; // call recursively if ((++current) < 26) startSelect(); }, 1000); } 
 .user-selected { color: red; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <select name="country" id="country-select" multiple size="5"> <option value="austria">Austria</option> <option value="belgium">Belgium</option> <option value="bulgaria">Bulgaria</option> <option value="croatia">Croatia</option> <option value="republic">Republic of Cyprus</option> <option value="czech">Czech Republic</option> <option value="denmark">Denmark</option> <option value="estonia">Estonia</option> <option value="finland">Finland</option> <option value="france">France</option> <option value="germany">Germany</option> <option value="greece">Greece</option> <option value="hungary">Hungary</option> <option value="ireland">Ireland</option> <option value="italy">Italy</option> <option value="latvia">Latvia</option> <option value="lithuania">Lithuania</option> <option value="luxembourg">Luxembourg</option> <option value="malta">Malta</option> <option value="netherlands">Netherlands</option> <option value="poland">Poland</option> <option value="portugal">Portugal</option> <option value="romania">Romania</option> <option value="slovakia">Slovakia</option> <option value="slovenia">Slovenia</option> <option value="spain">Spain</option> <option value="sweden">Sweden and the UK</option> </select> </form> 

而且由於他們顯然使用{ behavior: "auto" }選項來調用它,因此您甚至無法確定setTimeout(fn, 0)足以抵消它。

但是對於您想做的事情,也許<form>元素的reset()方法可能適合,甚至只是<button type="reset"> 這些不受此怪異行為的影響:

 var $form = $('form'); var $select = $form.find('select'); $form.on('reset', function() { $select.scrollTop(0); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <select name="country" id="country-select" multiple size="5"> <option selected value="austria">Austria</option> <option value="belgium">Belgium</option> <option value="bulgaria">Bulgaria</option> <option value="croatia">Croatia</option> <option value="republic">Republic of Cyprus</option> <option value="czech">Czech Republic</option> <option value="denmark">Denmark</option> <option value="estonia">Estonia</option> <option value="finland">Finland</option> <option value="france">France</option> <option value="germany">Germany</option> <option value="greece">Greece</option> <option value="hungary">Hungary</option> <option value="ireland">Ireland</option> <option value="italy">Italy</option> <option value="latvia">Latvia</option> <option value="lithuania">Lithuania</option> <option value="luxembourg">Luxembourg</option> <option value="malta">Malta</option> <option value="netherlands">Netherlands</option> <option value="poland">Poland</option> <option value="portugal">Portugal</option> <option value="romania">Romania</option> <option value="slovakia">Slovakia</option> <option value="slovenia">Slovenia</option> <option value="spain">Spain</option> <option value="sweden">Sweden and the UK</option> </select> <button type="reset">Reset form</button> </form> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM