簡體   English   中英

在for循環中覆蓋JavaScript事件

[英]JavaScript event being overwritten in for loop

我正在循環中的項目上創建JavaScript事件,但每次觸發事件時它都會觸發創建的最后一個事件。

JavaScript的:

var dirLinks = document.getElementsByClassName("dirLink"),
    iframe   = document.getElementById("tmpImg");

showDir.addEventListener('click', showDirContent, false);
showImgs.addEventListener('click', showImgsContent, false);

for (var i = 0; i < dirLinks.length; i++) {
    var link = dirLinks[i];
    link.onclick = function () {
        updateIframeSource(link.getAttribute("imgSrc"));
    }
}

function updateIframeSource(source) {
    iframe.src = source;
}

HTML:

<a class="dirLink" imgSrc="img1.jpg" href="#">img1.jpg</a><br />
<a class="dirLink" imgSrc="img2.jpg" href="#">img2.jpg</a><br />
<a class="dirLink" imgSrc="img3.jpg" href="#">img3.jpg</a><br />
<a class="dirLink" imgSrc="img4.jpg" href="#">img4.jpg</a><br />
<a class="dirLink" imgSrc="img5.jpg" href="#">img5.jpg</a>

<iframe id="tmpImg"></iframe>

沒有哪一個環節我事點擊,它會一直打到updateIframeSource與功能img5.jpg傳入。

這是因為在javascript for循環中不會在每次迭代中創建新的作用域(只有函數可以)所以你引用一個變量link ,它在循環結束時執行的函數中,所以它總是5,修復它只是包裝整個事物在這樣的匿名函數中:

for(var i = 0; i < dirLinks.length; i++) {
    (function(link) {
        link.onclick = function () {
            updateIframeSource(link.getAttribute("imgSrc"));
        };
    })(dirLinks[i]);
}

這是因為循環不會創建新范圍。 因為javascript有函數范圍:

var bindEvent = function(intId){
     var link = dirLinks[intId];
     link.onclick = function () {
            updateIframeSource(link.getAttribute("imgSrc"));
     }
}

for(var i = 0; i < dirLinks.length; i++) {
    bindEvent(i);
}

jsfiddle

也用這個

for(var i = 0; i < dirLinks.length; i++) {
    var link = dirLinks[i];
    link.addEventListener("click", updateIframeSource());
}

function updateIframeSource() {

    return (function(event){
      iframe.src  = event.target.getAttribute("imgSrc");
      alert(iframe.src);
    });



}

分配事件處理程序的操作很昂貴,最好包裝所有錨鏈接並使用事件委托:

這里如何:

<div id="container">
    <a class="dirLink" imgSrc="img1.jpg" href="#">img1.jpg</a><br />
    <a class="dirLink" imgSrc="img2.jpg" href="#">img2.jpg</a><br />
    <a class="dirLink" imgSrc="img3.jpg" href="#">img3.jpg</a><br />
    <a class="dirLink" imgSrc="img4.jpg" href="#">img4.jpg</a><br />
    <a class="dirLink" imgSrc="img5.jpg" href="#">img5.jpg</a>
</div>
<script>
var dirLinks = document.getElementsByClassName("dirLink");
var iframe = document.getElementById("tmpImg");
// Get the container
var container = document.getElementById("container");

//showDir.addEventListener('click', showDirContent, false);
//showImgs.addEventListener('click', showImgsContent, false);

container.addEventListener('click', function(evt){
    // You can send the event or extract like this the value of "imgsrc"
    updateIframeSource(evt.target.attributes.imgsrc.value);
});

function updateIframeSource(source) {
    iframe.src = source;
}
</script>

這是forEach循環的另一種方式

HTML:

  <a class="dirLink" imgSrc="img1.jpg" href="#">img1.jpg</a>
  <br />
  <a class="dirLink" imgSrc="img2.jpg" href="#">img2.jpg</a>
  <br />
  <a class="dirLink" imgSrc="img3.jpg" href="#">img3.jpg</a>
  <br />
  <a class="dirLink" imgSrc="img4.jpg" href="#">img4.jpg</a>
  <br />
  <a class="dirLink" imgSrc="img5.jpg" href="#">img5.jpg</a>

  <iframe id="tmpImg"></iframe>

JS:

var dirLinks = document.getElementsByClassName("dirLink");
var iframe = document.getElementById("tmpImg");

[].forEach.call(dirLinks, (l) => {
  l.addEventListener('click', function() {
    updateIframeSource(l.getAttribute("imgSrc"));
  })
})

function updateIframeSource(source) {
  iframe.src = source;
}

暫無
暫無

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

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