2016-11-17 69 views
-1

我遇到了一个Javascript函数的问题,该函数显然会被调用得太快。我有一种预感,这是一个悬念问题,但我不确定。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();   
 
    
 
}

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

+3

问题是图片的尺寸未知unti l图像成功*加载*。你需要在图像中添加一个'onload'监听器。有关重复问题,请参阅http://stackoverflow.com/a/626505/1902010。 – ceejayoz

+2

提升不会马上执行您的功能。 – Gavin

+1

JavaScript **是一种“常规”编程语言。 –

回答

3

你需要等待图像加载:

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();   
    } 
} 

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

  1. 首先,用一次性的处理程序挂钩load事件(one)。
  2. 然后,设置src
  3. 检查图像是否已经完成:如果是,请删除处理程序并立即调用您的函数;否则,当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>

+0

@richdotjs:不,“一”,而不是“开”。这是一个一次性处理程序。 –

+0

嗯。我尝试了你的方法,就像在我拷贝你的代码一样 - 但它的行为完全一样。执行adjustModalPadding时,图片的高度仍为零。完成一个实际的方法/财产?我会说不(缺少(),它不会显示在自动完成菜单中)。也许你的意思是把它当作'检查图像是否完整'的简写,但实际上我不知道该怎么做。 – Nicola

+0

@Nicola:'complete'是一个实际的属性:https://www.w3.org/TR/html5/embedded-content-0.html#dom-img-complete如果上面没有,我会很惊讶,工作。但是,如果没有,你可能会考虑用全新的'img'元素替换*'#g-modal-img',而不是仅仅改变它的'src'(在设置'src'之前再次挂载load'等)。 –

-1

当加载图像您可以使用事件:

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

logo.addEventListener("load", function() { 
    adjustModalPadding();   
}; 
+1

我尽量避免使用'.onload',而是使用'。的addEventListener(“负荷”,()= {})' – MayorMonty

+0

是的,它是更好的选择:) – user2693928

+0

相同的答案上面试过你的方法,但画面的高度仍然记录为零。 – Nicola