簡體   English   中英

onclick不會在首次點擊時觸發,可排序列表,JavaScript

[英]onclick not firing on first click, sortable list, JavaScript

我正在嘗試列出一個列表,其中每行可以通過按一個按鈕來上下移動。

我在按鈕上使用onclick方法,並以“ this”作為參數。

頁面加載后,需要點擊幾下才能觸發該事件。

之后,需要1到3次點擊。

這是為什么?

<!doctype html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">    

    <title>Schedule</title>
</head>
<body>
<div id="eXes">
  <div class="eX">
    1
    <button class="up" onclick="moveUp(this)">up</button>
    <button class="down" onclick="moveDown(this)">down</button>
  </div>
  <div class="eX">
    2
    <button class="up" onclick="moveUp(this)">up</button>
    <button class="down" onclick="moveDown(this)">down</button>
  </div>
  <div class="eX">
    3
    <button class="up" onclick="moveUp(this)">up</button>
    <button class="down" onclick="moveDown(this)">down</button>
  </div>
</div>

<script type="text/javascript">
    function moveUp(el) {
        var selected = el.parentNode;
        var previous = el.parentNode.previousSibling;
        document.getElementById("eXes").insertBefore(selected, previous);
    }
</script>
<script type="text/javascript">
    function moveDown(el) {
        var selected = el.parentNode;
        var next = el.parentNode.nextSibling;
        document.getElementById("eXes").insertBefore(selected, next.nextSibling);
    }
</script>
</body>
</html>

實時代碼https://www.w3schools.com/code/tryit.asp?filename=FIAIQO31H90L

您的問題是每個div之間的空白。 瀏覽器將此作為textNode對待,因此當您最初向上或向下移動元素時,實際上只是將其與空白交換。 上下單擊2-3次后,就可以將空白有效地“排序”到dom堆棧的底部,然后您就再也看不到問題了。

一種快速的解決方案是通過更改標記以關閉並打開div彼此相鄰而不是換行的方式來刪除空白。

您可以在此處閱讀有關空白的更多信息: https : //developer.mozilla.org/zh-CN/docs/Web/API/Document_Object_Model/Whitespace_in_the_DOM

如果您使用console.log el.parentNode.previousSilbing,則會看到每個div之間都有一個“ nextLine” el,因此只需刪除它即可,但是會使html看起來很丑。

 <!doctype html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Rota Schedule</title> </head> <body> <div id="eXes"> <div id='1' class="eX"> 1 <button class="up" onclick="moveUp(this)">up</button> <button class="down" onclick="moveDown(this)">down</button> </div><div div id='2' class="eX"> 2 <button class="up" onclick="moveUp(this)">up</button> <button class="down" onclick="moveDown(this)">down</button> </div><div div id='3' class="eX"> 3 <button class="up" onclick="moveUp(this)">up</button> <button class="down" onclick="moveDown(this)">down</button> </div> </div> <script type="text/javascript"> function moveUp(el) { console.log('click',el.parentNode,el.parentNode.previousSibling) var selected = el.parentNode; var previous = el.parentNode.previousSibling; document.getElementById("eXes").insertBefore(selected, previous); } </script> <script type="text/javascript"> function moveDown(el) { var selected = el.parentNode; var next = el.parentNode.nextSibling; document.getElementById("eXes").insertBefore(selected, next.nextSibling); } </script> </body> </html> 

previsousSibling和nextSibling返回前一個或后一個兄弟。 在您的情況下,每個之間

...
</ div>
<div class="ex">
...

因此,如果您使用console.log(上一個),則結果將是文本而不是元素。

如果這樣做,您的問題將得到解決

<div class="eX">
1
<button class="up" onclick="moveUp(this)">up</button>
<button class="down" onclick="moveDown(this)">down</button>
</div><div class="eX">
 2
<button class="up" onclick="moveUp(this)">up</button>
<button class="down" onclick="moveDown(this)">down</button>
</div><div class="eX">
 3
<button class="up" onclick="moveUp(this)">up</button>
<button class="down" onclick="moveDown(this)">down</button>
</div>

但這會使您的代碼可見性最差。

您應該做的就是使用函數來獲取好的元素。 在您的情況下,您必須替換previsousSibling和nextSibing為

function previousElementSibling( elem ) {

do {

    elem = elem.previousSibling;

} while ( elem && elem.nodeType !== 1 );

return elem;
}

function nextElementSibling( elem ) {

do {

    elem = elem.nextSibling;

} while ( elem && elem.nodeType !== 1 );

return elem;
}

嘗試以下操作,我將刪除按鈕中每個向下或向上的onClick事件,並使用Arrary.prototype和forEach選擇元素:

 Array.prototype.slice.apply(document.querySelectorAll('.up')).forEach(function (el){ el.addEventListener('click',function(){ var selected = el.parentNode, previous = el.parentNode.previousSibling; document.getElementById("eXes").insertBefore(selected, previous); }); }); Array.prototype.slice.apply(document.querySelectorAll('.down')).forEach(function (el){ el.addEventListener('click',function(){ var selected = el.parentNode, next = el.parentNode.nextSibling; if(next == undefined){ next = document.getElementById("eXes").firstChild; } document.getElementById("eXes").insertBefore(selected, next.nextSibling); }); }); 
 <div id="eXes"> <div class="eX"> 1 <button class="up">up</button> <button class="down">down</button> </div> <div class="eX"> 2 <button class="up">up</button> <button class="down">down</button> </div> <div class="eX"> 3 <button class="up">up</button> <button class="down">down</button> </div> </div> 

的ForEach

foreach函數會在數組中的foreach每執行一次回調函數,請訪問此鏈接以獲取更多信息: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

暫無
暫無

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

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