#javascript #jquery
#javascript #jquery
Вопрос:
Я пытаюсь воспроизвести функцию ширины jQuery, используя чистый JavaScript. Функции чистого JavaScript, такие как getComputedStyle или offsetWidth, похоже, работают, если элемент виден, но я не могу воспроизвести то же поведение, когда элемент скрыт.
Кажется, что jQuery делает здесь что-то другое, и я не могу понять, что именно.
Чтобы четко объяснить, что я пытаюсь сделать, вот пример codepen, где я пробую getComputedStyle в сравнении с функцией jQuery width для вычисления ширины скрытого элемента, который динамически изменяется.
const input = $('input');
const sizer = $('.sizer');
const sizerDom = document.querySelector('.sizer');
input.on('input', evt => {
sizer.text(evt.target.value);
console.log(sizer.width())
console.log(getComputedStyle(sizerDom, null).width);
});
.sizer {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text">
<span class="sizer">
Ответ №1:
Это связано с тем, что во внутренней логике jQuery, это взаимно меняет display
свойство с none
на другое значение, так что это заставляет браузер мгновенно отобразить его. В противном случае измерения будут всегда, 0
поскольку элемент никогда не отображается.
Кроме того, вместо того, чтобы пытаться использовать window.getComputedStyle
который вернет строковое значение размера CSS (например, 100px
), вы можете использовать sizerDom.getBoundingClientRect()
для получения фактического числа вместо этого (которое возвращает, скажем, 100
) без необходимости выполнять дополнительный синтаксический анализ.
const input = $('input');
const sizer = $('.sizer');
const sizerDom = document.querySelector('.sizer');
input.on('input', evt => {
sizer.text(evt.target.value);
console.log(sizer.width())
const cachedDisplay = window.getComputedStyle(sizerDom).display;
sizerDom.style.display = 'inline-block';
console.log(sizerDom.getBoundingClientRect().width);
sizerDom.style.display = cachedDisplay;
});
.sizer {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text">
<span class="sizer">
Комментарии:
1. OP хотел получить ширину
hidden
элемента в JS — вы делаете это с помощью какого-то взлома для использованияinline-block
— Что не очень идеальное или желаемое решение в соответствии с названием этого вопроса —getBoundingClientRect()
не работает сhidden
элементами.2. @AlwaysHelping Я не совсем уверен, в чем ваша проблема: OP спрашивает, как jQuery это делает, и я просто показал ему «взлом», который jQuery использует для определения размеров явно скрытого элемента. Не очень соответствует вашему имени пользователя?
3. Пожалуйста, не принимайте мои комментарии на свой счет. Мне нравится взлом, который вы сделали, честно. Я никогда не думал об этом. Согласно вопросу OP, я предположил, что он хотел специально для hidden
el
в чистом JS безhack
отличного ответа, я ценю это!