Почему $('# foo'). Css ('width', $('# foo'). Css ('width')) изменить ширину?

Можно подумать, что после следующего бит jQuery ширина div, выбранная #foo, не изменилась бы вообще; в конце концов, мы устанавливаем эту ширину в значение, которое оно якобы уже имеет:

var original_width = $('#foo').css('width');
$('#foo').css('width', original_width);

Фактически, это разумное предположение кажется неправильным, как показано на этой странице . Я даю код ниже. Важно отметить, что четыре основных раздела, соответствующие четырем .level-0 div s, имеют одинаковую структуру и контент. Второе и четвертое из них (которые имеют класс jqbug) имеют свою "перестановку" ширины (с некоторым количеством JS, как описано выше) до значения, которое оно предположительно уже имеет. Для второго случая ширина фактически изменяется этой операцией; для четвертого случая ширина остается неизменной, как и ожидалось. Единственное различие между определениями второго и четвертого случаев состоит в том, что первый имеет border-box для своего параметра box-sizing.

<div class="level-0 border-box">
    <div id="i1" class="level-1">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0 border-box">
    <div class="level-1 jqbug">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0">
    <div id="i1" class="level-1">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0">
    <div class="level-1 jqbug">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js">
</script>


  (function ($) {
    $('.jqbug').each(function () {
      $(this).css('width', $(this).css('width'));
    });

  }(jQuery));


*{
  outline:3px solid green;
}

.border-box, .border-box *{
  -webkit-box-sizing:border-box;
     -moz-box-sizing:border-box;
          box-sizing:border-box;
}

.level-0{
  position:relative;
  margin:10px auto;
  width:300px;
  height:100px;
  font-family:consolas,monaco,courier,monospace;
}
.level-1{
  position:absolute;
  padding:10px 20px;
  background-color:#0aa;
  font-size:15px;
}

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

Мои вопросы:

  • Является ли это ошибкой в ​​jQuery или это загадочное поведение каким-то образом согласуется с спецификацией CSS?

  • Что нужно сделать, чтобы получить результат jsFiddle, похожий на результат, созданный браузером?

EDIT: я изменил JS (как на странице, указанной выше, так и на jsFiddle, а также в этом сообщении), чтобы соответствовать тому, что было дано в ответе Марко Бискаро; это не имело никакого отношения к появлению страницы, отображаемой непосредственно браузером, но это повлияло на внешний вид результата jsFiddle. Теперь последний не показывает разницы в ширинах различных div. Этот результат по-прежнему отличается от того, который создается непосредственно браузером, поэтому ситуация не намного лучше, чем раньше: у нас все еще есть, что jQuery производит неожиданные результаты, а jsFiddle дает результаты, которые не соответствуют результатам браузера.

Ответ 1

У вас есть два разных div с одним и тем же классом. Когда вы выполните:

$('.jqbug').css('width')

Возвращается ширина одного из div (я точно не знаю, как jQuery определяет, какая из двух). На вашей размещенной странице возвращаемое значение 234px, а в jsFiddle - 274px (опять же, я точно не знаю почему). Вот почему поведение отличается от двух страниц.

Это возвращаемое значение применяется как ширина обоих div, но поскольку у одного div есть box-sizing: border-box, а у другого нет, один div становится больше другого.

jQuery не изменит ширину любого div, как и ожидалось, если вы установите ширину как исходную ширину и используйте $(document).ready (http://bugs.jquery.com/ticket/14084):

$(document).ready(function () {
    $('.jqbug').each(function () {
        $(this).css('width', $(this).css('width'));
    });
});

Ответ 2

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

border-box имеет установленную на нем модель размера рамки. Это означает, что он принимает ширину + дополнение.

Это приведет к переопределению встроенной ширины, заданной jquery.

Ответ 3

Просто возьмите внешнюю ширину, он рассчитает фактическую ширину, включая отступы и границу

var original_width = $('#foo').outerWidth();