使用jQuery的AJAX计时问题

时间:2014-04-09 19:36:22

标签: javascript jquery asp.net ajax

我搜索过每一个地方,并且我已经在这里工作了好几个小时。基本上,我有一个Ajax调用从网页中获取数据,该数据从数据库中获取数据。此代码用于图片库的幻灯片演示。整个功能如下所示,但是无法正常工作的部分是获取图像高度和宽度的两行代码。

图像正在被正确提取,并且它们显示正常(不是真的,但它们会显示出来)。查询图像的行'宽度和高度,返回0 大多数的时间。他们返回正确值的概率大约为5%。这会导致之后的if语句始终评估为false,这会使宽图像延伸到网页的边缘。

此问题仅出现在基于Webkit的浏览器中。基于Gecko的浏览器没有这个问题。

我认为问题是jQuery试图在Ajax调用完成请求之前查询图像。有没有办法让jQuery等待Ajax完成它的请求?

function LoadForm() {
    GalleryDataSource = new kendo.data.DataSource({
        transport: {
            read: {
                url: BaseAPI + "/PhotosByAlbum2",
                dataType: "json",
                data: { "location": locationID, "ID": $.getQuery('ID') }
            }
        }
    });

    $("#slides").kendoListView({
        dataSource: GalleryDataSource,
        template: kendo.template($("#SlidesTemplate").html())
        });

    $.ajax({
        type: "Get",
        contentType: "application/json; charset=utf-8",
        url: BaseAPI + "/PhotosByAlbum2",
        datatype: "json",
        data: { "location": locationID, "ID": $.getQuery('ID') },
        success: function (d) {
            for (var i = 0; i < d.length; i++) {
                $('#Show').append(
                    '<figure><img src="' + d[i].Path +
                    '" id="' + d[i].ID +
                    '"/><figcaption>Title: ' + d[i].Title + '<br />' +
                    'Description: ' + d[i].Description +
                    '</figcaption></figure>'
                );

/*these do*/    var imgheight = $("#" + d[i].ID).height();
/*not work*/    var imgwidth = $("#" + d[i].ID).width();

                if (imgheight < "768" && imgwidth > imgheight) {
                    $("#" + d[i].ID).addClass("wideimage");
                } else {
                    $("#" + d[i].ID).addClass("tallimage");
                }
            }

            $('#Show').innerfade({
                animationtype: 'fade',
                speed: 1050,
                timeout: 2000,
                type: 'sequence',
                containerheight: '500px'
            });
        }
    });

    $('#back').click(function () {
        window.location = 'Photos.aspx'
    });
}

注意:我已尝试使用$.when(*ajax call here*).done(function() {*do stuff*});。它的行为完全相同。

我已尝试将async选项设为false。同样的行为。

我还尝试在Ajax调用中添加complete事件处理程序。同样,它表现得一样。

3 个答案:

答案 0 :(得分:1)

如评论中所述,在加载图像之前,您无法访问图像的高度和宽度。我会做这样的事情来监听加载事件:

$.each(d, function (idx, item) {
    $fig = $('<figure/>');
    $('<figcaption/>')
        .html('Title: ' + item.Title + '<br />Description: ' + item.Description)
        .appendTo($fig);

    $('<img/>')
        .load(function () {
            var $this = $(this);
            var height = $this.height();
            var width = $this.width();
            if (height < "768" && width > height) {
                $this.addClass('wideimage');
            } else {
                $this.addClass('tallimage');
            }
        }).attr('id', item.ID)
        .attr('src', item.Path)
        .appendTo($fig);

    $fig.appendTo('#Show');
});

答案 1 :(得分:0)

正如我在评论中所说,你必须等待图像加载才能可靠地获得它们的宽度并设置你想要的类。

这是一种重新构建ajax调用的方法,只有在加载图像后才处理图像,并且只有在图像被加载并正确标记后才启动动画:

$.ajax({
    type: "Get",
    contentType: "application/json; charset=utf-8",
    url: BaseAPI + "/PhotosByAlbum2",
    datatype: "json",
    data: { "location": locationID, "ID": $.getQuery('ID') },
    success: function (d) {
        var imagesRemaining = d.length;
        for (var i = 0; i < d.length; i++) {
            var img = new Image();
            img.src = d[i].Path;
            img.id = d[i].ID;
            img.onload = function() {
                --imagesRemaining;
                var item = $(this);
                var imgheight = item.height();
                var imgwidth = item.width();

                if (imgheight < 768 && imgwidth > imgheight) {
                    item.addClass("wideimage");
                } else {
                    item.addClass("tallimage");
                }

                // now see if all images are loaded now
                // so all classes are set so we can now start the animation
                if (imagesRemaining === 0) {
                    $('#Show').innerfade({
                        animationtype: 'fade',
                        speed: 1050,
                        timeout: 2000,
                        type: 'sequence',
                        containerheight: '500px'
                    });
                }
            };
            $("<figure>").append(img).append('<figcaption>Title: ' + d[i].Title + '<br />' +
                'Description: ' + d[i].Description + '</figcaption>').appendTo("#Show");

        }

    }
});

答案 2 :(得分:0)

我做到了......当然,可能有更好的方式...

在运行于BaseAPI +&#34; / PhotosByAlbum2&#34;的php脚本中; ...获取每个图像的宽度和高度,如果需要,将图像的大小调整为幻灯片放映的正确高度和宽度,然后将这些变量放在结果数组中,包含路径,标题和描述...

在jQuery上...读取数组并调整html中的宽度和高度......