Pull to refresh

Comments 33

и небольшой вопрос в догонку:
заботит ли вас быстродействие какого-либо выбранного способа изменения стилей, например при анимации?

а вот собственно небольшой тест jsperf.com/style-vs-csstext-vs-setattribute
по небольшим итогам видно что воздержалось почти половина голосовавших
можно предположить что они пользуются фреймворками и только ими

и еще раз повторю — для тех кто сразу минусует: я вовсе не против фреймворков — просто бывают специфические задачи и требования

а также интересен вариант тех 50 человек кто выбрал 4-й пункт опроса
Лучше предположите, что почти половина — не верстальщики, и далеки от html'ов c css'ами
а смысл тогда воздерживаться или вообще как-то отвечать если не знаешь про что вопрос
Можешь знать, про что вопрос, но не пользоваться этим вовсе.
Мне, к примеру, был интересен результат.
блин, точно — пока не проголосуешь не показывает же результат, совсем вылетело из головы (
похоже минусующие не знают данных способов изменения стилей (
жаль жаль…
наверное все больше $el.css(...)? да?
к сожалению это грустная правда
очень многие как бы "знают" javascript на уровне — "нахожу нужный плагин"
хотя с другой стороны — а оно им надо?
Насколько я могу понять, тут чистого JS и нет. Jquery сплошной.
Я стараюсь переопределить стили в файле css для нужных элементов.
Не совсем правильно я написал. Смутило el ^-)
конечно это чистый js
Первый кажется должен быть самым медленным так как дважды дергается DOM, по этому лучше конечто третий вариант, если надо изменять несколько свойств одновременно.
однако по ссылочке на тест пока что он оказывается самым быстрым в большинстве браузеров — или тест не совсем правильно показывает
Ну не знаю. У меня в Firefox 16.0.2 и в Опере 12.10 под Linux x86_64 самый быстрый — setAttribute().
В Chromium 23.0.1271.64 самый быстрый — style.width.
вот уже немного подсобиралась статистика
Chrome 23.0 — 64 теста — - лидирует (~1.3 раза) — el.style.width
Оpera 12.10 — 10 тестов — лидирует с небольшим отрывом el.style.width
Firefox 16.0 — 33 теста — лидирует с приличным отрывом (почти 2 раза) — setAttribute
Совершенно верно, при каждом присвоении нового значение будет произведён ре-рендеринг элемента. Но, третий вариант перезапишет уже имеющиеся инлайновые стили. Если нужно перебрать действительно большое количество элементов, то лучше банально поставить их контейнеру display: none, после чего перебирать. Скрытые элементы и/или не вставленные в DOM не будут заново ре-рендериться пока их не отобразишь \ вставишь.
по вашему рецепту к сожалению ничего не изменилось в скорости
jsperf.com/style-vs-csstext-vs-setattribute/2
а из за лишних двух операций со стилями контейнера (display: none — display: block) лично у меня даже чуть-чуть медленней стало
Совершенно верно, при каждом присвоении нового значение будет произведён ре-рендеринг элемента.
Насколько я помню, это произойдет не сразу. Только при необходимости. Т.е. можно сколь угодно много писать в el.style, reflow и repaint произойдут только при чтении какого-либо DOM свойства, или при завершении скрипта.
Если элемент не вставлен в DOM тогда да, если вставлен, то при каждом изменение. Причём даже когда ставишь одинаковые значение происходит рендеринг на каких-то браузерах, уже не помню.
Возможно, нужно тестировать. Из личного опыта заню, что браузеры, во всяком случае Chrome и Opera, очень хорошо умеют оптимизировать этот процесс, стараясь все максимально кэшировать, собирают потенциальные рефлоу в батчи, и распознают, когда нужно делать рефлоу или репаинт. Если изменение style.width заведомо не влияет на соседние элементы, то Chrome будет делать только repaint. Если же влияет, то до repaint произойдет ещё style recalculation и reflow/layout. Нужно, пожалуй, поэкспериментировать. Статьи на тему похоже уже устарели. В той же Opera советуют использовать cssText/setAttribute, хотя в тестах изменение style у них показывает наилучшие результаты.
На этой же странице

var divs = document.querySelectorAll("div"); for (var i = 0; i < divs.length; i++) { divs[i].style.width=(divs[i].offsetWidth-1) + "px" };

В Chrome вызвал N последовательностей recalculate style > layout > layout. И одному финальному repaint. В то время как

var divs = document.querySelectorAll("div"); for (var i = 0; i < divs.length; i++) divs[i].style.width='80%';

приводит лишь к одному проходу recalculate style > layout > layout > repaint, что кстати говорит о том, что возможно автор топика тестировал совсем не то, что хотел.
мне как раз и надо было как в вашем втором примере — что бы не было лишнего recalculate
если просто менять стили — то браузер действительно откладывает все пересчеты до определенного момента
а вот в первом случае этот момент настает когда мы запрашиваем ширину элемента divs[i].offsetWidth

именно поэтому не стоит делать так
width = el.offsetWidth
el.style.width = width + 10 + "px"
height = el.offsetHeight
el.style.height = height + 10 + "px"

а лучше сначала прочитать все нужные свойства и лишь затем их изменять
width = el.offsetWidth
height = el.offsetHeight
el.style.width = width + 10 + "px"
el.style.height = height + 10 + "px"

Может лучше присвоить класс и манипулировать стилями класса?
При анимации тоже будете менять классы? Конечно если только анимация не на transition.
А представьте, что нужна анимация нескольких элементов. Будете менять стили индивидуально?

Кажется на хабре уже было про решение менять CSS в head, навешанные на элементы через классы или id.
Вы себе представляете функцию для анимации хотя бы, или лишь бы ляпнуть? В любом случае решение быстрее не будет, так как основное время всё равно занимает рендеринг элемента, а способ данный метод не меняет.
Изначально речь вообще про анимацию не шла. Это вы про неё заговорили. Кроме того, может решение и быстрее не будет, но возможностей чуть больше: Cascade Sheet, псевдо-классы… Хотя конечно это всё by design.
> Изначально речь вообще про анимацию не шла.
Первый комментарий автора поста.
Хотя в чём-то, пожалуй соглашусь, но пока не вижу сильных преимуществ, зависит от адекватности первоначальной вёрстки.
Интересен вариант когда производится ручное изменение ксс. После изменения элементу назначается новый класс. Примерно как дабл баффер — на каждый элемент 2 класса и манипуляции с неиспользуемым.
интересует как раз таки динамическое изменение +-сотни элементов — у всех соотв. разные значения
Вы занимаетесь ерундой, как и обхаивая фреймворки. Используйте тот способ который является правильным/быстрым под текущую задачу, а если будет тормозить в каком-то браузере — оптимизируйте под него. А лучше — используйте фреймворк, где это чаще всего работает и кроссбраузерно, и быстро. Я на pure js уже давно не пишу, и уверен что сохранил себе кучу нервов и времени на другие полезные и менее скучные решения.
согласен и вовсе не против фреймворков — просто бывают специфические задачи и требования
поэтому вопрос в заголовке топика считаю вполне корректным
Sign up to leave a comment.

Articles