Нахождение ширины скрытого элемента, аналогичного jQuery, в чистом javascript

#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">  

https://codepen.io/OmranAbazid/pen/OJNXyoG

Ответ №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 отличного ответа, я ценю это!