【问题标题】:Is there a 'ready' event fired when a jQuery element is created on the fly?动态创建 jQuery 元素时是否会触发“就绪”事件?
【发布时间】:2010-06-22 21:36:21
【问题描述】:

我正在尝试在 jQuery 中实现类似照片轮播的功能。这个轮播可以使用图像源数组填充图像(我发出一个 ajax 请求,返回带有此数据的 json),一旦填充,您可以调用几个方法,previous() 和 next() 来移动轮播分别向后和向前。

问题是这个功能已经实现并且可以工作,但我无法解决调整大小过程的问题。为了避免图像超出容器的边界,如果需要,我有一个创建和调整图像大小的方法。

this.getImageResized = function(imageSrc) {

    var image = $('<img />', {src : imageSrc});

    // Container ratio
    var ratio = this.itemMaxWidth / this.itemMaxHeight;

    // Target image ratio is WIDER than container ratio
    if((image[0].width / image[0].height) > ratio) {
        if(image[0].width > this.itemMaxWidth) {
            image.css('width', this.itemMaxWidth + 'px');
            image.css('height', 'auto');
        }
    // HIGHER
    } else {
        if(image[0].height > this.itemMaxHeight) {
            image.css('width', 'auto');
            image.css('height', this.itemMaxHeight + 'px');
        }
    }

    // Embeds image into a wrapper with item's width and height
    var wrapper = $('<span style="display : block; float : left; width : ' + this.itemMaxWidth + 'px; height : ' + this.itemMaxHeight + 'px"></span>');

    image.appendTo(wrapper);

    return wrapper;
};

测试此功能,我发现有时,图像的大小没有按预期调整。我使用 firebug console.log() 来记录 jQuery 元素创建下方的 image[0].width,发现有时该值为 0。

我不是 jQuery 专家,但我想当这种情况发生时(值为 0)是因为元素还没有准备好。

当我询问元素的宽度和高度值时,如何确保元素已经加载?

这样的事情可能吗?

var image = $('<img />', {src : imageSrc}).ready(function() {
    // But image[0].width it's not available here!
});

感谢您的帮助!

【问题讨论】:

  • jQuery event for images loaded 的可能重复项
  • @spender - 请查看我对 Sarfraz 的回答的 cmets...这不是同一个问题,也不是合适的答案,这不应该作为重复关闭...因为,好吧,这是一个不同的问题。
  • @Nick,我只能认为您没有发现 Sarfaz 正在使用窗口加载事件,但链接问题中的答案使用了图像加载事件。我会发布一个答案来演示,但这确实没有必要。
  • @spender - 一个答案使用它......同样不正确,您需要在src 设置之前附加负载处理程序,即使使用缓存它也不会不能跨浏览器工作...请参阅下面的答案以了解如何适当地处理此问题。不要相信我的话,看.load()的文档:“如果从浏览器缓存加载图像,可能不会触发加载事件。考虑到这种可能性,我们可以测试图片的.complete 属性的值。"

标签: jquery


【解决方案1】:

您想在这种情况下使用load 事件,如下所示:

var image = $('<img />', {src : imageSrc}).one('load', function() {
  // use this.width, etc
}).each(function() {
  if(this.complete) $(this).load();
});

最后一点会触发load 事件,以防它已经被触发...在某些浏览器中从缓存加载图像时不会发生这种情况,使用.one() 只触发一次,然后.complete 检查是否已加载。

【讨论】:

  • 没有one方法,应该改成on
【解决方案2】:

没有平台兼容的方法来查看 DOM 对象是否“准备就绪”,请参阅 https://developer.mozilla.org/en/DOM_Events 了解壁虎特定事件

【讨论】:

    【解决方案3】:

    根据here提供的答案,我拼凑了一个工作演示:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
      <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
      <script type="text/javascript">
       //<![CDATA[
        $(window).load(function(){
         //window load already fired
         setTimeout(function(){ 
          var img=$('<img />'); 
          img.appendTo($("body"));
          img.load(function(){alert("img is "+$(this).width()+"px wide.")});
         },5000) //5 secs delay. definitely adding "dinamically" 
          img.attr("src","http://sstatic.net/so/img/sprites.png");
        });
       //]]>
      </script>
     </head>
     <body>
    
     </body>
    </html>
    

    【讨论】:

    • 这里有几件事要解决,这不处理缓存的情况(在所有浏览器中都不会触发load,请参阅我的回答),它应该只是img.appendTo("body"), 而你如果这样做,则应在设置源之前附加load 处理程序,否则它肯定不会从 any 浏览器中的缓存中触发您的负载处理程序,事件可能会在有处理程序之前触发.
    • 修复了订单...其余部分我将重新实现您的答案! ;)
    猜你喜欢
    • 2012-07-28
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多