2011-05-25 88 views
16

我得到一些html并插入它与.html(),之后我试图得到一个新插入的元素与.width()(其中有一个CSS规则)之一的宽度。然而,有时 - 宽度没有拿起,并返回为0.jQuery:为什么在使用.html()插入元素后,.width()有时会返回0?

是因为JS运行在新创建的元素和他们的CSS“前面”?我已经尝试链接.html('...').find('...').width(),但它仍然有时不起作用。这是什么原因,是否有解决方法?

编辑:应广大用户要求,例:

/* ajax.response is: 
    <div class="boxes"> 
     <div class="box width-A">test 1</div> 
     <div class="box width-B">test 2</div> 
     <div class="box width-C">test 3</div> 
    </div> */ 

var boxOutput = $('.boxOutput'); /* .boxOutput is already on the page */ 
boxOutput.html(ajax.response); 

// make width of ".boxes" equal to the sum of all ".box" 

var boxWidth = 0; 
$('.box', boxOutput).each(function(i) { 
    boxWidth += $(this).width(); /* this is where sometimes width returns 0 */ 
}); 
$('.boxes', boxOutput).css('width', boxWidth); 

我原来的代码太长/丑复制/粘贴,但是这是我做的一个简单的确切的事情(很抱歉,如果有一个愚蠢的在某个地方犯错,我太迟了:P)。从ajax获取html后,将其放入div中,我想获得每个框的宽度(因为它可能不同),然后使用该宽度。再次,90%的时间,宽度被正确地返回。当有时宽度为0时,这是10%:(

+2

你能告诉它与返回0,确切的代码?另外,哪些浏览器? – alex 2011-05-25 23:35:52

+0

元素内是否有图像?你还在用WebKit进行测试吗? – alex 2011-05-25 23:36:50

+2

如果所讨论的元素是图像,则只要图像尚未完成加载,就会返回零值... – 2011-05-25 23:37:01

回答

24

取决于什么浏览器。偶尔我会发现javascript运行时的同步渲染期望会有所改变,并且我需要在下一个tick中获得结果。

我想尝试:

$(elem).html(data); 
setTimeout(function(){ 
    // Get the width here 
},0); 
+0

嗨乔希,我猜这里有一些赛车状况。在所有的事情中,你的setTimeout方式似乎适用于我。我想不是最优的解决方案,但它的工作原理!我也很高兴知道我不是唯一一个有这种奇怪行为的人,嘿嘿。谢谢:) – 2011-05-26 17:47:04

+0

确认我在Chrome 26.0.1410.64中看到了这种间歇性行为。有时第一次显示复杂的对话框时,width()返回0(对于在对话框创建期间已动态插入到DOM中的元素),但大多数情况下会返回正确的宽度。必须是竞赛条件。 – 2013-05-23 21:45:53

+1

10年来,我已经避免使用setTimeout来补偿浏览器/ js持久性问题......我从来没有意识到你可以使用0的时间,虽然......非常好。 – dsdsdsdsd 2013-07-13 10:13:52

0

不确定是100%,但我认为你的问题是在附加元素的函数之外调用的代码不能识别新创建的元素。 :

<div id="container"> 
</div> 

<script> 
    $(document).ready(function() { 
     $('#container).html('<p style="width:200px">Lorem ipsum</p>'); 
     alert($('#container p').width()); // alerts 0 
     $('#container p').html('Lorem ipsum dolor sit amet'); // if content doesn't change, it's clearly a problem of jquery not being able to bind the functions to your new elements 
    }); 
</script> 

如果你能告诉我们你在做什么正是我们一定会找到解决的办法

以后编辑

现在,您发布的代码,其实我可以帮忙。您需要运行以下代码:

$('.box', boxOutput).each(function(i) { 
    boxWidth += $(this).width(); /* this is where sometimes width returns 0 */ 
}); 

函数在您的ajax响应函数中。例如:

$.get('script.php', function(data) { 
    $('#elem').html(data); 
    // your code for width() 
}); 

希望这会有所帮助。

+0

在原帖子中发帖子。是的,我恐怕它不知道里面的元素。有些时候它不能工作时会感到沮丧。我总是可以用另一种方式获得所需的结果 - 从来没有遇到过这样的事情,并且对实际发生的事情更感兴趣。 – 2011-05-26 00:23:34

+0

嗨Claudiu,我没有得到Ajax回应的问题。在我将html放入之后,我正处于某种竞速状态.Josh的解决方案似乎工作至今。 – 2011-05-26 17:49:27

9

jQuery将返回一个零宽度如果元素是不可见的。例如,我遇到与插入到隐藏表单选项卡上的项目相同的问题。它暂时分配给体,它是可见的,我能够确定宽度:

$("body").append(el); // First assign it to the body so that it's visible 
var width = el.width(); // The width will now be correct 
wrapper.append(el); // Now place the element where you want it. 

一个需要注意的是,如果当分配给体元素继承不同的样式,则宽度可能不正确。

+0

概念上很聪明。我是一个在飞行中隐藏操纵以实现特定目标的巨大粉丝。 – 2016-07-18 19:54:47

0

我们发现,的document.ready不够好所以300ms的效果很好:

setTimeout(function() { 
     resizeHeightOfMyDiv(); 

     $(window).on("resize", function() { 
      resizeHeightOfMyDiv(); 
     }); 
    }, 300); 
0
// ... 
$('.box', boxOutput).each(function(i) { 
    //boxWidth += $(this).width(); /* this is where sometimes width returns 0 */ 
    boxWidth += this..getBoundingClientRect().width; 
}); 
//... 
相关问题