Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 24.05.2012, 00:23
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

css.js - fast as a shark.

Версия 1.0.1
Код тут.

Введение : когда я писал ф-ю анимирования, в классическом режиме (т.е. манипуляции с style элемента) мне потребовалась функция установки стилей. Т.е. эта функция - решение одной из подзадач анимирования. Функция получилась довольно неплохой (об этом ниже), и я решил выложить её на форум.

Плюсы :
  1. Очень быстрая (см. сравнение в блоке ссылок, в нижней части поста).
  2. Очень простая.
  3. Гибкая в использовании.
  4. Возможность ускорить самостоятельно (см. внизу).
  5. Расширяема, за счёт использования хуков.
Минусы :
  1. В IE < 9 не работает transform и другие CSS3 св-а, т.к. они там не поддерживается. К выходу версии 2 добавлю хуки для частоиспользуемых свойств. Сам хук для transform сейчас есть, но он сырой.
  2. Оперирует только с CSSStyleDeclaration (для этого и задумывалась). Поэтому получить значение высчитанного стиля сама не может. (если вы сами вычисленный стиль не передадите).

О скрипте:
Функция создает\заменяет существующее свойство css объекта window. Window.css является callable-object, т.е. вызывается, и содержит свойства.

Вызов функции происходит так :
var style = document.body.style;
css(style, { "font-size": "16px", "float": "right", "borderWidth": "20px" });

Он и является одним из самых быстрых способов установки стиля элементу.

Ещё можно так :
var style = ...;
css(style, "font-size", "16px");
css(style, "borderWidth": "20px");

но тогда стираются различия в производительности между этой функцией и другими.

Получение значений стиля :
просто пропустите третий аргумент и передайте второй как строку.
var style = ...;
css(style, "font-size"); // "16px"
css(style, "borderWidth"); // "20px"

Функция не оперирует с элементами. Она оперирует именно со свойством style - CSSStyleDeclaration.

Свойства window.css :
  • attachHook( propName, action, func)

    Добавит хук на свойство propName, на действие action.
    Action может быть либо "get", либо "set" - на получение свойства, или на назначение свойства соответственно. Об установке хуков см. ниже.
  • lowlevel ( style, property_name, property_value )

    низкоуровневая функция для установки одного значения, или же для получения значения, если не передано значение свойства - value, или оно равно undefined. Используется в window.css. "Низкоуровней" не значит "лучше" - функция по скорости такая же, как и вариант от jQuery. Используйте window.css для большей скорости.
  • normalize (css_property_name)

    Попытается превратить CSS-свойство в свойство CSSStyleDeclaration. Подберёт префикс к свойству, если нужно.
    Не работает со свойствами, содержащих в себе вендорный префикс (она сама его подберёт).
    Есть возможность ускорить её работу (ниже)

Каждая функция по-умолчанию возвращает true в случае успеха, и false в случае неудачи (при получении значения свойства при удаче возвращается значение св-а).


Об установке хуков :
Хуки не удаляются, они только добавляются. Хук не добавляется для двух операций (get и set) за раз. Хук исполняется в тот момент, когда функция сама не может установить значение свойству, или получить значение свойства.

Когда хук исполняется, в него передаются следующие аргументы :
  1. Текущий CSSStyleDeclaration.
  2. Имя свойства.
  3. Значение свойства
  4. Объект кэша.
    Объект кэша - обычный объект. Приватен, т.е. для каждого свойства имеется свой кэш.

Об ускорении css.normalize:
Дело в том, что функция кеширует результат работы в объекте. Если поместить одинаковые во всех браузерах свойства (вроде border-style), то функция не будет вычислять их, а просто будет сразу брать готовые значения оттуда. Эдакая "база данных", или "холодный кеш".
Кешем является локальная переменная normalized - обычный объект. Ключом в нём является CSS-свойство, а значением - свойство CSSStyleDeclaration.

Пример :
normalized = {
    "border-style": "borderStyle"
}

Разумеется, не надо сохранять в нём свойства, типа "transform".

Можно сделать по-другому. В конце использования ф-и ставим точку останова на window.css, и вызываем её (css) без аргументов. Так мы получим доступ к локальным переменным.

Далее, в консоли пишем :
normalized.toSource()

*для этого нужно использовать dev-версию - исходник, или же найти имя normalized самому.

Далее, удаляем оттуда свойства с префиксами, заменяем старый normalized на полученный, и сжимаем её - ф-я почти одинаково жмётся в GCC в обоих режимах.
Реализовывать ли для этой мелочи отдельный метод, не уверен.
Возможно, позже добавлю уже готовый кеш.

Код с комментариями и его немного. К описанным функциям есть JSDoc.
Код функции нигде не публикуется, кроме форума. Я решил, что для Github она маловата.
И ещё, она будет включена в функцию анимирования. так что Вы её ещё увидите .

Ссылки :
Итак, сам код тут.
Сравнение сделал тут. Включите консоль для отображения результатов. В FF мой способ быстрее стандартного на 70%.

Последний раз редактировалось melky, 26.05.2012 в 10:20.
Ответить с цитированием
  #2 (permalink)  
Старый 26.05.2012, 00:48
Аватар для Раед
''
Отправить личное сообщение для Раед Посмотреть профиль Найти все сообщения от Раед
 
Регистрация: 11.12.2011
Сообщений: 636

Сообщение от css.js
style.cssText = interim.cssText;
Я конечно могу ошибаться, но по-моему эта строка сбросит все стили, установленные JavaScript'ом ранее
Ответить с цитированием
  #3 (permalink)  
Старый 26.05.2012, 01:54
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

что то твой пример у меня совсем не работает, или твой скрипт не рассчитан для оперы?
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #4 (permalink)  
Старый 26.05.2012, 09:43
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Раед Посмотреть сообщение
Я конечно могу ошибаться, но по-моему эта строка сбросит все стили, установленные JavaScript'ом ранее
да, сейчас исправлю.

Сообщение от devote Посмотреть сообщение
что то твой пример у меня совсем не работает, или твой скрипт не рассчитан для оперы?
рассчитан какая версия оперы? у меня 11.64 Linux, работает. здесь тест функции.

__________________________________________________
Обновил версию в gist'e.

что сделал:
  • удалил функцию isCorrect за ненадобностью. теперь скрипт весит 1.17кб minified
  • исправил "фичу" с заменой стилей. теперь ф-я не удаляет старые стили. спс
__________________________________________________ _
в хроме ф-я заметно тормозит. это из-за повешенного getter'a и setter'а на свойство cssText. я сейчас над этим работаю.

Последний раз редактировалось melky, 26.05.2012 в 10:23.
Ответить с цитированием
  #5 (permalink)  
Старый 26.05.2012, 14:02
Аватар для Раед
''
Отправить личное сообщение для Раед Посмотреть профиль Найти все сообщения от Раед
 
Регистрация: 11.12.2011
Сообщений: 636

melky,
Позволь поинтересоваться, зачем в сжатом варианте певой строчкой объявляется глобальная переменная g?
Сообщение от css.js
var g=!1;
Что-то GCC поднахимичил...
Ответить с цитированием
  #6 (permalink)  
Старый 26.05.2012, 15:56
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от Раед Посмотреть сообщение
melky,
Позволь поинтересоваться, зачем в сжатом варианте певой строчкой объявляется глобальная переменная g?

Что-то GCC поднахимичил...
вероятно, так ужимается false
Ответить с цитированием
  #7 (permalink)  
Старый 26.05.2012, 16:08
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от melky
вероятно, так ужимается false
ну дык всунь его вручную так:
(function(g){
// ... more code
})(!1);
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #8 (permalink)  
Старый 26.05.2012, 16:22
Аватар для Раед
''
Отправить личное сообщение для Раед Посмотреть профиль Найти все сообщения от Раед
 
Регистрация: 11.12.2011
Сообщений: 636

Сообщение от melky
вероятно, так ужимается false
Это ясно, но зачем он его в глобальную область выкинул
Ответить с цитированием
  #9 (permalink)  
Старый 26.05.2012, 16:27
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от Раед
Это ясно, но зачем он его в глобальную область выкинул
в ADVANCED режиме он всегда так делает, ради уменьшения файла, и такие переменные как false. true, null он кидает в глобалку если видит что это приводит к меньшему размеру файла. Поэтому эти переменные потом нужно вручную переместить.
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
  #10 (permalink)  
Старый 26.05.2012, 17:40
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Сообщение от devote Посмотреть сообщение
в ADVANCED режиме он всегда так делает, ради уменьшения файла, и такие переменные как false. true, null он кидает в глобалку если видит что это приводит к меньшему размеру файла. Поэтому эти переменные потом нужно вручную переместить.
странно, но в режиме advanced получается размер на 0.01кб больше. пожмите сами.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск