Javascript函数调用太快[重复]

Posted

技术标签:

【中文标题】Javascript函数调用太快[重复]【英文标题】:Javascript function called too soon [duplicate] 【发布时间】:2017-04-01 04:12:33 【问题描述】:

我遇到了一个 javascript 函数的问题,该函数显然被调用得太早了。我有预感这是一个吊装问题,但我不确定。

所以,我有一个分配给onclick<img> 的函数:

function setModalPicture(picName)
    
    //Build the path to the picture
    var pic= 'assets/img/art/'+picName;
      
    //Set the picture
    $('#g-modal-img').attr('src', pic);    
    
    adjustModalPadding();          
    

意图是将#g-modal-img 的src 属性设置为img,然后才应调用adjustModalPadding。这是因为adjustModalPadding 需要#g-modal-img 的高度,在src 设置为<img> 之前为零。但是,我注意到这不能正常工作,如果我让adjustModalPadding 将#g-modal-img 的高度记录到控制台,它显示为零。我认为这意味着该函数在 src 设置为<img> 之前被调用。

【问题讨论】:

问题是图像的尺寸在图像成功加载之前是未知的。您需要为图像添加一个onload 侦听器。有关重复问题,请参阅 ***.com/a/626505/1902010。 吊装不会很快执行你的功能。 而 JavaScript 一种“常规”编程语言。 我并不是故意不尊重 Javascript。 :) 我认为这是一个提升问题,并且由于我在 Javascript 之前从未见过提升,因此从这个意义上说,它对我来说不是一种“常规”语言。没有冒犯的意思。 :) 另外,当然是关于图像尚未加载的问题!抱歉,没有考虑清楚。我实际上在教程中看到了类似的东西,但我一生都记不起那里是如何处理的。 【参考方案1】:

您需要等待图片加载:

function setModalPicture(picName)

    //Build the path to the picture
    var pic= 'assets/img/art/'+picName;

    //Set the picture
    var img = $('#g-modal-img');
    img.one("load", adjustModalPadding).attr('src', pic);
    if (img[0].complete) 
        img.off("load", adjustModalPadding);
        adjustModalPadding();          
    

注意上面的顺序,因为它很重要:

    首先,使用一次性处理程序 (one) 挂钩 load 事件。 然后,设置src。 检查图像是否已经完成:如果是,删除处理程序并立即调用您的函数;否则,当load 触发时,它将调用adjustModalPadding 并将其作为处理程序删除。

您可能想要添加错误处理...


这是一个工作示例:

function setModalPicture(picName) 

  //Build the path to the picture
  var pic = picName; // 'assets/img/art/'+picName;

  //Set the picture
  var img = $('#g-modal-img');
  img.one("load", adjustModalPadding).attr('src', pic);
  console.log("img[0].complete after setting src: " + img[0].complete);
  if (img[0].complete) 
    img.off("load", adjustModalPadding);
    adjustModalPadding();
  


function adjustModalPadding() 
  var img = $("#g-modal-img")[0];
  console.log("Size: " + img.width + "x" + img.height);

$("input[type=button]").on("click", function() 
  console.log("img[0].complete before starting: " + $("#g-modal-img")[0].complete);
  setModalPicture("https://graph.facebook.com/1035045703246692/picture?type=large");
);
<!-- In a comment, you said it starts out with src="" -->
<img id="g-modal-img" src="">
<input type="button" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

这在 Chrome、Firefox 和 IE11 中适用于我。


或者,您可以通过克隆创建替换 img 元素:

function setModalPicture(picName) 

  //Build the path to the picture
  var pic = picName; // 'assets/img/art/'+picName;

  //Set the picture
  var img = $("#g-modal-img");
  var newImage = img.clone();
  img.replaceWith(newImage);
  newImage.one("load", adjustModalPadding).attr('src', pic);
  console.log("newImage[0].complete after setting src: " + newImage[0].complete);
  if (newImage[0].complete) 
    newImage.off("load", adjustModalPadding);
    adjustModalPadding();
  


function adjustModalPadding() 
  var img = $("#g-modal-img")[0];
  console.log("Size: " + img.width + "x" + img.height);

$("input[type=button]").on("click", function() 
  console.log("img[0].complete before starting: " + $("#g-modal-img")[0].complete);
  setModalPicture("https://graph.facebook.com/1035045703246692/picture?type=large");
);
<!-- In a comment, you said it starts out with src="" -->
<img id="g-modal-img" src="">
<input type="button" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

这在 Chrome、Firefox 和 IE11 中也适用于我。


最后,您可以从头开始创建替换 img 元素(不是克隆):

function setModalPicture(picName) 

  //Build the path to the picture
  var pic = picName; // 'assets/img/art/'+picName;

  //Set the picture
  var img = $("#g-modal-img");
  var newImage = $("<img>").attr("id", "g-modal-img");
  img.replaceWith(newImage);
  newImage.one("load", adjustModalPadding).attr('src', pic);
  console.log("newImage[0].complete after setting src: " + newImage[0].complete);
  if (newImage[0].complete) 
    newImage.off("load", adjustModalPadding);
    adjustModalPadding();
  


function adjustModalPadding() 
  var img = $("#g-modal-img")[0];
  console.log("Size: " + img.width + "x" + img.height);

$("input[type=button]").on("click", function() 
  console.log("img[0].complete before starting: " + $("#g-modal-img")[0].complete);
  setModalPicture("https://graph.facebook.com/1035045703246692/picture?type=large");
);
<!-- In a comment, you said it starts out with src="" -->
<img id="g-modal-img" src="">
<input type="button" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【讨论】:

@richdotjs:不,one,不是on。这是一个一次性的处理程序。 嗯。我尝试了你的方法——例如,我照原样复制粘贴了你的代码——但它的行为方式完全相同。执行 adjustModalPadding 时,图片的高度仍然为零。完成一个实际的方法/属性吗?我会说不是(缺少 () 并且它没有显示在自动完成菜单中)。也许您的意思是“检查图像是否完整”的简写,但实际上我不知道该怎么做。 @Nicola:complete 是一个实际属性:w3.org/TR/html5/embedded-content-0.html#dom-img-complete 如果上述方法不起作用,我会相当惊讶。但如果不是,您可以考虑替换 #g-modal-img 用一个全新的img 元素,而不是仅仅更改它的src(在设置src 之前再次挂钩load 等.). 我试试,谢谢 我正在使用 Firefox,但我通过找到一种 CSS 方法来解决此问题,以执行 adjustModalPadding 正在执行的操作。不再需要检查图像是否已加载 :) 感谢您的帮助!【参考方案2】:

可以在图片加载时使用事件:

var logo = document.getElementById('g-modal-img');

logo.addEventListener("load", function() 
     adjustModalPadding();          
;

【讨论】:

我尽量避免使用.onload,而是使用.addEventListener("load", () = ) 是的,这是更好的选择:) 与上面的答案相同-尝试了您的方法,但图片的高度仍记录为零。 如何计算高度

以上是关于Javascript函数调用太快[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在C#后面调用Javascript函数[重复]

Javascript onkeyup延迟函数调用[重复]

奇怪的匿名javascript函数调用[重复]

无法从 Javascript 调用 PHP 函数 [重复]

Javascript调用错误的函数[重复]

调用 iframe 中定义的 Javascript 函数 [重复]