Подтвердить что ты не робот

JQuery: почему .width() иногда возвращает 0 после вставки элементов с .html()?

Я получаю некоторый html и вставляю его с .html(), после чего я пытаюсь получить ширину одного из вновь вставленных элементов с .width() (который имеет правило CSS). Однако иногда - ширина не поднимается и возвращается как 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). Получив html обратно из ajax, поместив его в div, я хочу получить ширину каждого окна (потому что он может быть другим), а затем использовать эту ширину. Опять же, 90% времени, ширина возвращается правильно. Это те 10%, когда иногда ширина равна 0: (

4b9b3361

Ответ 1

Зависит от того, какой браузер. Иногда я нахожу, что что-то сломается с синхронными ожиданиями рендеринга времени выполнения javascript, и мне нужно будет получить результат на следующем тике.

Я бы попробовал:

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

Ответ 2

jQuery вернет нулевую ширину, если элемент не отображается. Например, у меня была такая же проблема, когда элемент был вставлен на вкладку скрытой формы. Временно назначив его телу, где он был виден, я смог определить ширину:

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

Одно из предостережений заключается в том, что если элемент наследует разные стили при назначении телу, тогда ширина может быть неправильной.

Ответ 3

Не уверен 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 clearly a problem of jquery not being able to bind the functions to your new elements
    });
</script>

Если вы можете сказать нам, что вы делаете, мы обязательно найдем решение.

LATER EDIT

Теперь, когда вы разместили код, я действительно могу помочь. Вам нужно запустить этот код:

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

Надеюсь, что это поможет.

Ответ 4

Мы выяснили, что document.ready был недостаточно хорош, поэтому 300ms работало хорошо:

    setTimeout(function() {
        resizeHeightOfMyDiv();

        $(window).on("resize", function() {
            resizeHeightOfMyDiv();
        });
     }, 300);

Ответ 5

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