Jquery:.load()with for循环,总是接受元素

时间:2013-06-08 18:49:44

标签: jquery jquery-load jquery-get

我有一个jquery代码,它在我的图像上循环运行并逐个加载它们,除了将'a'标签插入结果中的最后一个图像这一事实之外,一切正常! 这是我的代码(请查看“var a”...它应该在每个循环中以不同方式插入变量'thissrc':

$.get(url, function (data) {
    var countImages = data.length;
    console.log("count: " + countImages);
    var $ul = $('#thumbs').empty();
    var counter = 0;
    for (var i = 0; i < countImages; ++i) {
        try {
            var description = data[i].desc[0];
        } catch (e) {
            description = '';
        }
        if (description == undefined) description = '';
        var thissrc = data[i].src;
        console.log("ME: " + thissrc);
        $('<img width="' + screen.width / 2.4 + '" alt="' + data[i].alt + '" title="' + description + '"/>').load(function () {
            ++counter;
            var $this = $(this);
            var $li = $('<span/>', {
                className: 'pic'
            });
            var $a = $('<a/>', {
                href: '#',
                    'id': 'rel',
                    'data-inline': true,
                    'data-transition': 'slide',
                className: 'show-page-loading-msg',
                    'data-referrer': 'photo_container',
                    'data-imgsrc': thissrc
            });
            $ul.append($li.append($a.append($this)));
            if (counter == countImages) {
                $thumbscontainer.append($ul.show());
            }
        }).attr('src', data[i].src);

    }
}, 'json');

提前致谢!

叶兰。

2 个答案:

答案 0 :(得分:0)

你应该能够通过回读图像的src来设置data-imgsrc,即:

'data-imgsrc': this.src

这是可靠的,假设在img创建之后和初始src成功加载之前没有其他代码有机会在短时间内更改src。

如果这不是一个安全的假设,那么解决方案会更精细,但并不罕见。

答案 1 :(得分:0)

一个常见的错误。问题归结为:

for (var i = 0; i < countImages; ++i) {
    var thissrc = data[i].src;
    setTimeout(function() {
        // Will only ever alert the last value of thissrc
        alert(thissrc);
    }, 100);
}

在JavaScript中,for构造(或任何常规块语句)不会创建新的词法范围。也就是说,每次迭代都使用相同的变量 thissrc。以上代码段等效于

var thissrc;
for (var i = 0; i < countImages; ++i) {
    thissrc = data[i].src;
    setTimeout(function() {
        alert(thissrc);
    }, 100);
}

实际上,函数内的每个变量声明(使用var)的范围都是到该函数

MDN explains the problem really well并使用额外功能提供解决方案。在这种情况下,它可能看起来像:

$.get(url, function (data) {
    // ...
    for (var i = 0; i < countImages; ++i) {
        // ...
        var thissrc = data[i].src;
        // ...
        // Make a new callback for $.load using the *current* value of thissrc
        $.load(url, makeCallback(thissrc));
    }
    // ...

    function makeCallback(thissrc) {
        // Yes, this function returns another function
        return function() {
             // Do your callback stuff here
        };
    }
}

请注意,因为makeCallback$.get的回调函数中定义了,所以它可以访问所有这些局部变量,例如counter和{{1 }}。这些变量在description范围内

JavaScript 1.7使let keyword

更容易实现
  

makeCallback允许您声明变量,将其范围限制为块,   语句或使用它的表达式。这与let不同   keyword,全局定义变量,或本地定义整个变量   无论块范围如何都可以起作用。

这意味着只需进行一项更改即可解决问题:

var

不幸的是,由于这是一个相当新的补充,它是not supported in old browsers