Можно ли получить доступ к текущему коэффициенту масштабирования элемента %-width с помощью Javascript, не вызывая перекомпоновки?

Я пытаюсь исправить медленно работающий javascript в медленном пользовательском интерфейсе, и я сузил основную причину до вызова jQuery .width(), используемого для просмотра фактического размера элемента width: 100% в пикселях в адаптивном макете, в процессе, который должно происходить часто в ответ на действия пользователя.

Я добавил измерения на основе меток времени, и они показывают, что только на них приходится около 33% времени задержки, что делает разницу между ощущением пользовательского интерфейса резким и вялым. Удалив эту строчку, пользовательский интерфейс кажется быстрым, но он ставит вещи не в то место...

Кажется точно установлено, что .width() относительно медленный в jQuery> 1.8 в основном по двум причинам:

  • #P4# <блочная цитата> #P5# #P6#
  • #P7# <блочная цитата> #P8#

Цель вызова width() в моем коде — посмотреть, уменьшился ли адаптивный дизайн и насколько. Ему нужно посмотреть на элемент-оболочку виджета, который имеет width: 100%; (но может быть в столбце или другом контейнере, в зависимости от того, на каком сайте/странице он размещен), и нужно увидеть, какой % от максимальной ширины этой оболочки он фактически показывает в .

Другой код, основанный на другой системе координат, дает мне местоположение в пикселях для метки, затем мне нужно использовать коэффициент масштабирования (по существу = $wrapper.width() / maxWidth;), чтобы уменьшить местоположение, чтобы, например, при просмотре страницы в узком окне/устройстве и размер оболочки составляет 50% от его максимального размера, верхнее и левое смещения меток составляют 50% от их значений по умолчанию.

Есть ли способ получить доступ к этим данным о том, насколько был уменьшен элемент %-width, не вызывая перекомпоновки и других вещей, которые замедляют вызовы .width()?

Вещи, которые я пробовал или исключил:

  • .outerWidth() работает так же медленно, как .width()
  • .get(0).clientWidth (чистый вариант Javascript / non-Jquery) также почти такой же медленный, как .width() (предположительно, поэтому виновником является перекомпоновка)
  • Я заметил, что в большинстве браузеров, если я делаю что-либо из этого, за которым следует любое из вышеперечисленных в другом измерении (например, .get(0).clientWidth, за которым следует .outerHeight()), вызовы после первого будут очень быстрыми (примерно в 20 раз быстрее) . Предположительно, поскольку перекомпоновка только что была выполнена и к свойствам элемента только что был получен доступ, они каким-то образом кэшируются. Но эффект не сохраняется для повторных вызовов функции, только в пределах одного вызова функции.
  • .css("width") явно бесполезно, потому что во всех случаях это просто дало бы мне 100%
  • Я думал получить ширину окна, но все усложняется в зависимости от макетов столбцов страницы, на которой размещается этот элемент. Например, если моя оболочка имеет макет с двумя столбцами, а окно немного шире, чем точка останова, которая сворачивает два столбца, окно будет шире, чем максимальный размер элемента оболочки, но элемент оболочки не будет в 100% от его максимальной ширины.

[ Обновление ] Я думал, что нашел способ обойти необходимость решения проблемы и расположить ярлыки без доступа к масштабированию элемент: поскольку у меня уже была переменная maxWidth в пикселях и смещения в пикселях, у меня было достаточно данных, чтобы вычислить процентное смещение для моих меток с leftOffset_px / maxWidth_px и topOffset_px / maxHeight_px, затем + '%' и применить это как смещение CSS top и left каждой метки. Это смехотворно быстрее - теперь менее 1 миллисекунды, настолько быстро, что моя функция на основе временных меток не может это измерить!

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


person user56reinstatemonica8    schedule 08.09.2016    source источник
comment
правильно ли я это читаю. чтение ширины любым из этих методов, возвращающих требуемое значение, вызывает перекомпоновку? ... читать?   -  person Jaromanda X    schedule 08.09.2016
comment
Вот как я понимаю то, что я прочитал: цитируется в Когда происходит перекомпоновка в среде DOM? Когда вы получаете измерение, которое необходимо вычислить, например, при доступе к offsetWidth, clientHeight или любому вычисляемому значению CSS (с помощью getComputedStyle() в DOM-совместимых браузерах или currentStyle в IE)   -  person user56reinstatemonica8    schedule 08.09.2016
comment
извините, я не могу помочь, но это интересно узнать   -  person Jaromanda X    schedule 08.09.2016
comment
Может быть, не использовать jQuery, поскольку jquery делает это с размером коробки? $элемент[0].offsetWidth; В любом случае, это звучит слишком сложно, вы уверены, что это не то, что вы можете сделать с чистым CSS?   -  person Jonas Grumann    schedule 08.09.2016
comment
Координаты для меток взяты из D3.js анализа географических векторов топографических данных, так что, к сожалению, нет, не совсем так! И чистый javascript .clientWidth - это одна из вещей, которые я пробовал - он вызывает перекомпоновку и такой же медленный. У меня была идея рассчитать % смещения, не глядя на DOM...   -  person user56reinstatemonica8    schedule 08.09.2016
comment
Я имею в виду, можете ли вы сами рассчитать ширину с помощью vanilla js, чтобы jquery и его в 100 раз более медленная вещь с размером коробки выпадали из контекста?   -  person Jonas Grumann    schedule 08.09.2016
comment
+1 за интересный вопрос о перекомпоновке. Но я согласен с @Jonas Grumann. Звучит так, как будто вы должны использовать CSS, а не jQuery.   -  person damos    schedule 08.09.2016
comment
@JonasGrumann Оказывается, вы в значительной степени правы: я не могу рассчитать смещение пикселей таким образом, но я нашел способ рассчитать его как ширину %, даже не глядя на DOM. Я обновил соответственно. Так что мне больше не нужен ответ (но мне все еще интересно узнать, возможно ли это, я понятия не имел, что происходит так много перекомпоновок, пока не исследовал это!)   -  person user56reinstatemonica8    schedule 08.09.2016
comment
Я тоже не знал. Рад слышать, что вы нашли свое решение.   -  person Jonas Grumann    schedule 08.09.2016


Ответы (1)


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

.root {
  position: relative;
}
.ruler {
  position: absolute;
  width: 100%;
}

_

<div class="root>
  ...
  <div class="ruler"></div>
</div>

-

var updatedWidth = $('.ruler').width()

(Хотя я согласен с комментариями о том, что вы должны попытаться решить проблему с помощью CSS)

person Hugo Silva    schedule 12.09.2016