Pull to refresh
69
0
Павел Довбуш @dpp

User

Send message
> Было бы разумно проверять в условии наличие тех свойств и методов, которые необходимо использовать:
> if (document.defaultView && …
там дело немного в другом document.defaultView есть и в Safari, но в Safari быстрее работает isHidden

>>Т.о. "универсальным решением" будет функция isHidden. ;)
> Обе isHidden жестко привязаны к имени класса, и, следовательно, не
> могут называться универсальными.
если они не привязаны к классу, то это должны быть не isHidden, а doParentshaveTheFollowingClassName ;) но если это принципиально, то исправить, чтобы имя класса передавалось параметром - не проблема.

> К тому же та, что внутри
> isHiddenFast будет работать некорректно (проблема: return !!p &&
> p!=b; => нет проверки класса элемента, если элемент - это body).
а какой смысл скрывать body? это сделано нарочно.

Таки собрался дать более четкое определение reflow. Думаю теперь все четко написано.

PS. спасибо большое за комментарии!
>>Коммитятся все отложенные reflow, а не только те...
Я думаю эта фраза некорректна. Я так написал чтоб было понятнее. reflow не связан с каким либо элементом, у reflow есть только точка старта, от которой распространяются изменения. И будет ли затронут тот или иной элемент зарание не известно.

>Вы ведь только теперь написали: "не только те" (об этом и речь).
Теперь понял, что Вы имели ввиду. Четкого определения reflow я не нашел ни на русском ни на английском. Если можете поправить определение reflow чтобы это было понятно - внесите свой вклад :)

>>Понятно почему? Если нет...
>А вот так не надо.
да ладно Вам, я ж по-доброму ;)

>>Мы получили универсальное решение...
>Проверьте свое "универсальное решение" на этом примере:
О! спасибо Вам большое за обнаружение этой ошибки.
В цитируемой статье явно указано, что вызов getComputedStyle также вызывает reflow, и причины отсутствия этого в IE и FF непонятны, хотя и радуют.

Теперь понятны "причины отсутствия" - по тому что не работает :)) Странно, что я не заподозрил подставу сразу.

Т.о. "универсальным решением" будет функция isHidden. ;)
да нет, просто прожки работающие без доса, юзая тока функции биоса. на сколько помню написал простейший файловый менеджер и текстовый редактор. потом забил...
Вы это имели ввиду:
function test_offset()
{
    var c=init();
    var o = document.getElementsByTagName('meta').item(0);
    profile('offsetHeight');
        for(var i=0; i<1000; i++){
            fnOffset(o);
            c.appendChild(t.cloneNode(true));
        }
    profileEnd();
    clean(c);
}

У меня цифры остаются прежними во всех браузерах.

Коммитятся все отложенные reflow, а не только те, которые связаны с каким-то элементом. Понятно почему? Если нет постараюсь объяснить еще раз.
почему этот процесс становится причиной повторного вывода (laying out) элемента?

Это не так. Этот процесс коммитит отложеные reflow. Если их небыло, то reflow не происходит - смотрите самый первый тест.

Что же произойдет в случае если они были.
Представьте, что в DOM есть таблица с двумя ячейками. Ширина таблицы - 100px, ширина ячейки - 50%.

examples

Мы меняем содержимое первой ячейки и хотим узнать какова ее ширина. Казалось бы - 50px. Сравним таблицы 1 и 2.
Как браузер должен отличить первый случай от второго? Для этого требуется сделать layout не только для самого элемента, но и для его детей. Теперь рассмотрим третий случай. Как мы видим от содержимого могут измениться параметры родительского элемента, что потребует его пересчета. Примеры 4 и 5.
Таким образом от изменившегося элемента распространяется лавина reflow.

Efficient JavaScript:
As stated earlier, the browser may cache several changes for you, and reflow only once when those changes have all been made. However, note that taking measurements of the element will force it to reflow, so that the measurements will be correct. The changes may or may not not be visibly repainted, but the reflow itself still has to happen behind the scenes.

This effect is created when measurements are taken using properties like offsetWidth, or using methods like getComputedStyle. Even if the numbers are not used, simply using either of these while the browser is still caching changes, will be enough to trigger the hidden reflow.
За сам пример - спасибо. Но если заменить top: -9999px на display:none то все по-прежнему работает. Какой тогда смысл использовать top: -9999px ?
за сам пример спасибо. Но если заменить top: -9999px на display:none, то все по прежнему работает. Какой смысл тогда использовать top: -9999px ?
хм, мне очень любопытно чем руководствовался человек поставивший минус комментарию. в статье ведь объясняется теория, объясняющая замедление. и это имеет отношние к любой библиотеке.
добавил еще одну страницу в статью с описанием этого решения.
Пожалуйста. :)
Если честно, прочитав заметку Владимира Токмакова, я сразу же подумал, что предлагаемый им подход не оптимален из-за reflow. Но это наложилось на очередное заявление одного знакомого, который ссылается на Кодоводство, как на библию, и на Лебедева, как пророка ее. Вот я и решил аргументировано объяснить, что прислушиваться к советам великих нужно, но также нужно понимать разницу между безоговорочным доверием и осознанным согласием. Это было поводом. А что получилось в результате – Вы видите. ;) Отсюда такой странный заголовок. Всю остальную мораль я убрал, чтобы не портить статью, а заголовок забыл.

На счет "оптимизаторства". Я учился программировать с ассемблера. Добивался, чтоб программки не тормозили на двойке с двумя метрами памяти и влезали в загрузочный сектор дискетки. Это наложило свой отпечаток на мое профессиональное развитие. Потом я изучил Си, затем Си++, но понимание того, как все устроено у компилятора внутри, было всегда. Затем я не мог принять интерпретируемые языки из-за того, что практически ни на что нельзя повлиять. Однако постепенно осознал, что скорость кода, в какой-то мере, допустимо приносить в жертву скорости разработки. Однако неоптимальный код я не могу писать до сих пор. Наверное, это стало чертой профессионального характера. А накопив багаж знаний по какому-либо языку или технологии, рефракторинг с целью оптимизации приходится проводить все реже.
да, спасибо, опечатка
а пример необходимости top: -9999px можно? я как-то никогда с таким не сталкивался. С visibility косяки у IE знаю, а с display не встречал
спасибо, опечатка.
А если необходимо узнать виден ли вложеный элемент? Такое бывает в сложных приложениях (н-р контрол в соседнем табе). И если есть десятка два контролов, это становится очень неудобно.
То, что я предложил в конце - это самое простое и правильное решение:
если мы договоримся, что скрытые элементы должны иметь класс hide, то все сведется к определению наличия этого класса у элемента или его родителей.
ну это я упоминал в первы строках моего коментария. Вопрос не в том, что замыкания неявно присутствуют везде, а в том, когда правильнее решать проблемы именно используя замыкания.
Еще стоит отметить следующие применения: псевдо-private члены класса, функции-генераторы.
что я еще забыл?
http://www.terrainformatica.com/?p=9
http://www.terrainformatica.com/?p=13

любопытно, что оттуда убрали мои замечания в коментариях. написано "2 Comments", а нет ни одного.
Замыкания (closures, delegates) – это одна из основных фишек JavaScript. Без нее реализация часто возможна только с использованием глобальных переменных, что на самом деле будет тем же самым замыканием, только не вокруг одной переменной, а вокруг всех переменных window. ;)

Для чего применяется:
- создать ссылку на вызов функции с параметрами (переданными при создании замыкания)
- создать ссылку на вызов функции в контексте объекта

Я использую вот такую функцию для создания замыканий:
/**
* Bind function to context
* @param {Object|HTMLElement} context
* @param {Function} fn
* @return {Function} function bound to context
*/
$.bind=function(context, fn /*args...*/)
{
    if(typeof(context)=='function'){
        var args=Array.prototype.slice.call(arguments,0)
        args.unshift(null);
        return $.bind.apply(this, args);
    }

    if(arguments.length==2){    // params on call
        return function(){
            fn.apply(context||null, arguments);
        };
    }else{    // params on create
        var args=Array.prototype.slice.call(arguments,2);
        return function(){
            fn.apply(context||null, args.concat(Array.prototype.slice.call(arguments,0)));
        };
    }
};

Столько всего наворочено только для удобства использования и оптимизации.

Самым простым вариантом будет такой:
/// delegate bound params on create, if none params on call
function delegate(that, thatMethod /*args...*/)
{
    if(arguments.length==2)
        /// params on call
        return function(){ return thatMethod.apply(that,arguments); };

    /// params on create
    var args=Array.prototype.slice.call(arguments,2);
    return function(){ return thatMethod.apply(that,args); };
}


На счет расточительства: как асемблерщик – асемблерщика я вас понимаю. Говорят, что из-за ООП программы на C++ медленнее программ на C в 10000 раз. Но ведь давно уже никто не говорит, что использовать ООП – расточительно. JavaScript сам по себе быстрый. Узкие места обычно кроются в его связке с DOM.
спасибо за карму. сегодня опубликую статью для публикации которой она мне была нужна.
спасибо, понятно.
т.е. тему для обсуждения сообществу я предложить не могу, а могу только участвовать в чужих дискуссиях. проблема в том, что активная дискуссия чаще всего длится меньше дня, а время для участия удается выбрать не всегда. на форумах, где активная тема всплывает вверх в этом смысле проще...

Information

Rating
Does not participate
Location
Москва и Московская обл., Россия
Date of birth
Registered
Activity