1

このサンプル コードを Google Chrome で実行すると、意図した動作 (現在のページのプレースホルダー イメージ タグ内にイメージを読み込む) が発生しません。showPic() が呼び出されたときに currPic の値を確認したところ、「未定義」です。パラメータを showPic に「anchors[i]」から「this」に変更すると機能することはわかっていますが、なぜそうなのかを理解しようとしていました。

function showPic(currPic) {
    var srcLoc = currPic.getAttribute("href");
    var placeHolder = document.getElementById("placeholder");
    placeHolder.setAttribute("src", srcLoc);
    var imgLabel = document.getElementById("imglabel");
    var currLinkTitle = currPic.getAttribute("title");
    imgLabel.firstChild.nodeValue = currLinkTitle;
}

function prepareGallery() {
    if(!(document.getElementsByTagName && document.getElementById)) return false;

    var imgGallery = document.getElementById("imagegallery");

    if(imgGallery) {
        var anchors = imgGallery.getElementsByTagName("a");
        var i;
        for(i = 0; i < anchors.length; i++) {
            anchors[i].onclick = function() {
                showPic(anchors[i]);
                return false;
        }  
        }
    }
}
4

3 に答える 3

0

クロージャーがどのように機能するかについての明白な声明が見られなかったので、ここに私の見解があります。

var i;
for(i = 0; i < anchors.length; i++) {
    anchors[i].onclick = function() {
        showPic(anchors[i]);
        return false;
    }
}

iループ内で変数を参照する方法に注目してください。ループの終わりまでに、値はiequalsになりanchors.lengthます。

したがって、関数のいずれかが実行されると、 への参照;の最後のインデックスの 1 つ後ろの位置を指します。これがあなたが見る理由です。onclickianchorscurrPicundefined

この問題に対する 1 つの解決策は、他の回答で示されています。現在のアンカーを参照するために使用し、関数にthis渡さないでください。anchors[i]onclick

同様の状況に遭遇する可能性があるため、次のiように値を閉じることにより、別の解決策を示します。

var i;
for(i = 0; i < anchors.length; i++) {
    anchors[i].onclick = (function(i) {
        // inside this function, i is closed over and won't change anymore
        return function() {
            showPic(anchors[i]);
            return false;
        }
    }(i));
}
于 2012-06-06T03:39:01.657 に答える