Почему $('# 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();