ФорумПрограммированиеJavaScript → 10 JavaScript функций на все времена

10 JavaScript функций на все времена

  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 13 ноября 2007 г. 7:25

    Top 10 custom JavaScript functions of all time - 10 JavaScript функций на все времена. Конечно, если вы используете какую-нибудь библиотеку вроде jQuery, эти функции вряд ли будут вам полезны. Но ознакомиться стоит.

    Источник: http://firescript.ru/2007/08/29/obratite-vnimanie-vypusk-3/

    Надеюсь не "БОЯН"….
    adw/0
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 13 ноября 2007 г. 23:40, спустя 16 часов 14 минут 36 секунд

    по русски

    Позволю себе прокамментить немножко функции и привести свои доработки.

    [size=11]Куки[/size]

    Приведенная функция getCookie() имеет совершенно жесткие глюки. Например, поиск куки в строке:
    var start = document.cookie.indexOf( name + '=' );

    Т.е. у нас кука, допустим, имеет имя "x". Ищем мы "x=". А что будет если так же есть кука с именем "sex"? Прально, мы можем напороться первым делом на нее. Совершенно жесткий незачот.
    Так же вместо нормальных encodeURIComponent и decodeURIComponent используются к делу не относящиеся escape/unescape.
    То есть работать это будет если мы только читаем при помощи getCookie, куки установленные setCookie.
    Если мы из getCookie будем пытаться читать куки пришедшие с сервера или на сервере читать установленные setCookie, то ничего хорошего не выйдет.

    Посему:

    var cookie = new (function() {

    var cash;
    var self = this;

    this.set = (
    function(name, value, expires, path, domain, secure)
    {
    var cook = name + "=" + encodeURIComponent(value);
    if (expires) {
    var t = new Date();
    t.setTime(t.getTime() + expires * 1000);
    cook += ";expires=" + t.toGMTString();
    }
    if (path) {
    cook += ";path=" + encodeURIComponent(path);
    } else if (path === undefined) {
    cook += ";path=/";
    }
    if (domain) {
    cook += ";domain=" + domain;
    }
    if (secure) {
    cook += "secure";
    }
    document.cookie = cook;
    if (cash) {
    cash[name] = value;
    }
    return true;
    }
    );

    this.get = (
    function(name)
    {
    if (cash) {
    return cash[name];
    }
    cash = {};
    var cook = document.cookie.split(";");
    for (var i = 0; i < cook.length; i++) {
    var c = cook.split("=");
    cash[c[0].replace(/^\s*/, "").replace(/\s*$/, "")] = decodeURIComponent(c[1].replace(/^\s*/, "").replace(/\s*$/, ""));
    }
    return cash[name];
    }
    );

    this.del = (
    function(name, path, domain)
    {
    self.set(name, "", -1, path, domain);
    if (cash) {
    cash[name] = undefined;
    }
    return true;
    }
    );

    })();


    Во-первых, создаем не кучу глобальных функций, а только один объект, после чего вызываем cookie.set(), cookie.get(), cookie.del()
    Во-вторых, path по умолчанию равен "/".
    В-третих, в качестве даты устаревания передается относительное время в секундах. То есть 3600 — кука на час.
    В-четвертых, кешируем результаты разбора строки с куками.
    В-пятых, нет вышеописанных глюков.


    [size=11]Бакс с кэшем[/size]


    function $(node, nocash)
    {
    if (typeof(node) == "object") {
    return node;
    }
    var callee = arguments.callee;
    if (!callee.cashEnable) {
    return document.getElementById(node);
    }
    if ((!nocash) && (callee.cash[node])) {
    return callee.cash[node];
    }
    return callee.cash[node] = document.getElementById(node);
    }
    $.cash = {};
    $.cashEnable = true;
    $.cashReset = (function() {$.cash = {};});


    Возвращает DOM-элемент. На входе сам элемент или его ID.
    С множеством аргументом не парюсь, так как необходимость в подобном возникает редко и спокойно решается чем-то вроде
    var elements = [$("a"), $("b"), obj];

    Результаты поиска по ID кешируются, что при большом количестве элементов дает достаточно ощутимый прирост скорости, по крайней мере на некоторых браузерах.
    При этом могут быть глюки, если вносятся изменения в DOM-дерево, после чего по ID ищутся динамически созданные элементы. Решается отключением кеша ($.cashEnable = false) либо указанием аргумента nocash.

    [size=11]inArray()[/size]

    Пример забавный, конечно. Но, прежде, чем изменять прототипы нужно убедится, что данная функция там не присутствует. Возможно её определила другая библиотека, а, возможно, она уже появилась в браузерах.

    Очень грустно, что и inArray не входит в ядро DOM

    Вообще глупость. Array встроенный ECMA-объект. К DOM никаким боком не относится.

    [size=11]toggle()[/size]

    А в подобных функциях можно использовать нашу любимую $:

    function toggle(obj) {
    var el = $(obj);
    //…
    }

    [size=11]addEvent()[/size]

    А мне так нравится :):


    function addEvent(node, event, handler)
    {
    var f;
    if (window.addEventListener) {
    f = (
    function(node, event, handler)
    {
    return $(node).addEventListener(event, handler, false);
    }
    );
    } else if (window.attachEvent) {
    f = (
    function(node, event, handler)
    {
    return $(node).attachEvent("on" + event, handler);
    }
    );
    } else {
    f = (
    function(node, event, handler)
    {
    return $(node)["on" + event] = handler;
    }
    );
    }
    addEvent = f;
    return f(node, event, handler);
    }


    Во-первых, используем всю ту же $(), позволяя пользователю передавать, как объект, так и ID.
    Во-вторых, при первом вызове функция переопределяется на нужную и теперь не будет каждый раз ненужных проверок и ветвлений.
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 4:55, спустя 113 дней 5 часов 15 минут

    "Так же вместо нормальных encodeURIComponent и decodeURIComponent используются к делу не относящиеся escape/unescape.
    То есть работать это будет если мы только читаем при помощи getCookie, куки установленные setCookie."
    Позвольте напомнить, что авторы англоязычные, и использование escape вполне оправдано. Авторы не обязаны подстраиваться под кириллическую кодировку, чтобы прослыть профессионалами.
    А ваши комментарии вполне дельные.
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 5:07, спустя 12 минут 17 секунд

    Если авторы подразумевают, что в куках будут содержаться только данные из базовой латиницы, то им и escape() не нужен.
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 5:19, спустя 11 минут 34 секунды

    Возможно, авторы хотели заэскейпить эти: (!#$%^&(){}[]=:;?'") символы. Вполне оправдано.
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 5:49, спустя 30 минут 13 секунд

    Совершенно без разницы, что это за символы. "&" или "ы". Они должны экранироваться и, желательно, по принятому стандарту. Точно так же, если setCookie в PHP установит куку с "&", в JS getCookie() её нормально не прочитает.

    Авторы не обязаны подстраиваться под кириллическую кодировку, чтобы прослыть профессионалами.

    Не под кириллическую, а под символы, не входящие в базовый набор.
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 5:52, спустя 2 минуты 30 секунд

    escape на самом деле сам по себе должен работать с кириллицей, но там есть ошибка, которая делает использование этой функции неправильным для кириллицы. То бишь закодировать-то она закодирует, но на сервере ее разобрать будет уже невозможно. В частности эту решение этой проблемы было написано давно, но найти можно на xpoint.ru
    Там приведена правильная функция escape (к несчастью надо признать, что и она не лишена ошибок).
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 5:56, спустя 4 минуты 30 секунд

    Разобрать будет возможно, но только вручную.
    А стандартными средствами она не приведется. Потому что первоначальный разбор GET и POST-параметров, а так же кодирование значений в setCookie осуществляется по другим алгоритмам (тем же, что используются в encodeURIComponent).
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 5:59, спустя 2 минуты 43 секунды


    Разобрать будет возможно, но только вручную.
    А стандартными средствами она не приведется. Потому что первоначальный разбор GET и POST-параметров, а так же кодирование значений в setCookie осуществляется по другим алгоритмам (тем же, что используются в encodeURIComponent).

    Правильно, вручную, это не лучшее решение. В принципе для правильного кодирования можно использовать escape с xpoint.ru, но быть очень внимательным - приходилось сталкиваться, когда их подмена производила интересные ошибки. А так - использование escape вполне оправдано и ругать там не за что.
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 6:09, спустя 10 минут 28 секунд

    Нет :) Для правильного кодирования нужно использовать encodeURIComponent. Потому что это стандартное кодирование, используемое повсеместно.
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 6:21, спустя 11 минут 47 секунд

    !*()' - эти символы недоступны для encodeURIcomponent, так что о стандартном поведении говорить рано.
    тогда как для escape - @*/+
    Что важнее - решать разработчику, но это не вопиющая ошибка, которая недопустима
    :)
  • Шуранов

    Сообщения: 15 Репутация: N Группа: Кто попало

    Spritz 6 марта 2008 г. 6:42, спустя 20 минут 37 секунд

    Да, и еще одна вещь. Функцию $ не рекомендовал бы к применению. Эту функцию часто используют библиотеки, вроде mootools, переопределение функции может привести к непредсказуемым последствиям (был печальный опыт).
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 6:44, спустя 2 минуты 13 секунд

    Это вопиющая ошибка, так как используется кодирование, отличное от кодирования, которое используется везде, что не позволяет работать с куками, созданными в обход вызова на клиенте setCookie. Ну и наоборот.
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 6 марта 2008 г. 6:45, спустя 1 минуту 1 секунду

    Функции типа "$" используют многие библиотеки. А так же они используют еще много различных имен. Переопределение любого из них может привести к неприятным последствиям.

Пожалуйста, авторизуйтесь, чтобы написать комментарий!