Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/12/2012 in all areas

  1. Мне давно было интересно как устроен всеми любимый jQuery и вот я решил засесть за него (благо что исходники у него открытые). И вот, по просьбе камрада mishka2 я рассказываю, что я выяснил, как работает этот фреймворк и как написать свой такой же. Прежде всего пара фишек яваскрипта, про которые не все начинающие знают: 1) Имена функций: В яваскрипте валидными считаются любые имена функций, которые начинаются с буквы, со знака доллара ($) и со знака подчеркивания (_). Так что когда вы используете ваш любимый jQuery, вызывая к примеру $(document), знайте, что вы вызываете функцию у которой имя $ и передаете ей в качестве аргумента document. 2) Вызов функций: Обычно все пишут какую-нибудь функцию, к примеру: function myFunc() { alert(1); } // или так var myFunc = function() { alert(1); } а потом вызывают ее, но многие не знают, что в яваскрипте можно вызвать функцию сразу при создании вот таким методом: (function() { // создаем функцию alert(1); })(); // и тут же вызываем ее 3) Переменные и функции: Яваскрипт - это объектно ориентированный язык программирования. В нем все является либо объектами, либо свойствами объектов. Даже если вы используете процедурный подход к программированию (создаете отдельные функции и оперируете ими), вы все равно создаете объекты, т.к. в яваскипте любая функция - это объект. Т.е. вы можете вызвать ее через оператор new и рабоать с ней как с объектом. Когда вы создаете переменную в глобальной области видимости, то она записывается как свойство глобального объекта window. Т.е.var a = 1; и window.a = 1 эквивалентны. Ну вот теперь многие вещи в jQuery станут понятны. Самое интересное в jQuery то, что как только вы поздключили его на страницу он у вас сразу инициализирован. Давайте посмотрим как это сделано. 1) Для начала давайте создадим наш объект, назовем его Helper, у него будет пока единственный метод init(), который должен будет инициализировать его. А делать наш объект будет всего одну вещь - находить по ID элемент на странице или получать уже найденный элемент как ноду и возвращать его: var Helper = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; } } Фишка в том, что нам надо будет обязательно инициализировать наш объект, для того чтобы он заработал, т.е. нам нужно будет где-либо на странице вызвать метод init(): alert(Helper.init('id_элемента')); Но нам то нужно получить что-то вроде такого: alert(Helper('id_элемента')); Тут то нам и приходит на помощь вызов функции сразу при создании, единственное, что нам потребуется это анонимная функция (т.е. функция без имени), которая будет вызываться сразу же после создания и вспомогательная функция, которая будет инициализировать наш объект и возвращать его: (function() { // анонимная функция var Helper = function(elem) { // вспомогательная функция return new Helper.foo.init(elem); // которая возвращает нам уже проинициализированный объект } Helper.foo = { // наш основной объект init: function(elem) { // метод, где происходит инициализация elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; // метод возвращает нам ссылку на ноду } } })(); // сразу же вызываем анонимную функцию У внимательного читателя должен возникнуть вопрос: "Откуда взялся Helper.foo? И почему именно так?". Все дело в наследовании прототипов. Вообще, прототипы в яваскрипте это довольно сложная для понимания штука. В конце я дам ссылки на ресурсы где про это можно почитать. Признаюсь, сам перечитывал раз 10, но все равно не понял до конца как они работают. Скажу лишь, что когда мы пишем new Helper.foo.init(elem);, то не создаем новый объект с именем Helper.foo как вы могли подумать, а создаем новый объект с именем Helper.foo.init (т.к. init() - тоже функция), у которого нет ни одного метода. И чтобы использовать все методы которые мы будем добавлять в Helper.foo в дальнейшем на понадобится переопределить прототип Helper.foo.init. Пока все это звучит очень запутанно, но я надеюсь, что когда вы увидите дальнейший код, то все поймете. Итак, теперь у нас есть проинициализированный объект и казалось бы мы можем его начать вызывать, но (как вы должны знать) переменная Helper у нас получилась не глобальной, т.к. она находится внутри анонимной функции. Чтобы начать использовать наш Helper нам надо передать его в глобальную область видимости, вот так это сделано в jQuery: (function() { // анонимная функция var Helper = function(elem) { // вспомогательная функция return new Helper.foo.init(elem); // которая возвращает нам уже проинициализированный объект } Helper.foo = { // наш основной объект init: function(elem) { // метод, где происходит инициализация elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; // метод возвращает нам ссылку на ноду } } // передаем переменную Helper в глобальную область видимости window.Helper = Helper; })(); // сразу же вызываем анонимную функцию Все, теперь вы можете использовать проинициализированный объект: <body> <div id="test"></div> <script type="text/javascript"> alert(Helper('test')); </script> </body> Но позвольте, откуда же в jQuery берется доллар? Все очень просто - пусть у нас будет два доллара: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; } } // создаем два доллара window.Helper = window.$$ = Helper; })(); И вызываем: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test')); </script> </body> Однако, если в jQuery вызвать $('#test'), то он вернет не ссылку на ноду а сам себя, т.е. объект jQuery и чтобы получить ссылку на ноду в jQuery нам придется сделать что-то вроде этого: <body> <!-- Используем jQuery --> <div id="test"></div> <script type="text/javascript"> alert($('#test')); // выведет [object Object] (сам себя) alert($('#test')[0]); // выведет [object HTMLDivElement] </script> </body> Все это потому, что все найденные элементы jQuery цепляет к себе. Ничто не мешает нам сделать так же: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem // цепляем элемент к объекту return this; // возвращаем не элемент, а наш объект } } window.Helper = window.$$ = Helper; })(); Вот у нас и получится тоже самое: <body> <!-- Используем наш фреймворк --> <div id="test"></div> <script type="text/javascript"> alert($$('test')); // выведет [object Object] (сам себя) alert($$('test')[0]); // выведет [object HTMLDivElement] </script> </body> Теперь давайте добавим в наш фреймворк какой-нибудь метод, например пусть у него будет имя getNodeName(), а возвращать он будет имя ноды: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem return this; }, getNodeName: function() { // наш новый метод // возвращает имя ноды найденного объекта в верхнем регистре return this[0].nodeName.toUpperCase(); } } window.Helper = window.$$ = Helper; })(); Давайте попробуем при помощи нашего нового метода узнать имя ноды: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test').getNodeName()); // Ошибка !!! </script> </body> Почему же это не работает? Как я уже говорил выше, вспомогательная функция Helper создает новый объект с именем Helper.foo.init, а внутри нашего метода init() нет никаких других методов. Поэтому нам надо переопределить прототип для Helper.foo.init, т.е. указать скрипту явно, что шаблоном нашего объекта является не Helper.foo.init, а Helper.foo. Причем наш объект foo должен храниться обязательно как свойство объекта Helper иначе (если я правильно понял, прочитав кучу статей про прототипы) переопределить прототип не получится. (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem return this; }, getNodeName: function() { return this[0].nodeName.toUpperCase(); } } Helper.foo.init.prototype = Helper.foo; window.Helper = window.$$ = Helper; })(); Вот теперь все заработает: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test').getNodeName()); // выведет DIV </script> </body> Ну вот и все, теперь вы можете расширять свой фреймворк, добавляя туда новые методы и использовать его так же как и jQuery. Теперь вы представляете как устроен этот фреймворк. Конечно то что я тут описал - это очень сильно упрощенная версия jQuery. Она умеет находить ноду только по ID и в ней нет кучи полезных фишек jQuery. Но я не волшебник, я только учусь. Многое еще остается в jQuery для меня не ясным, но надеюсь со временем я его таки доковыряю P.S. Что я читал: http://javascript.ru/ecma/part8#_Prototype_ http://javascript.ru/tutorial/object/inher...type-i-prototip http://code.jquery.com/jquery-1.4.2.js http://dklab.ru/chicken/nablas/40.html
    1 point
  2. Я не знаю, я не дизайнер. Сложно сказать. Ощущается что чего-то не хватает, что-то не дотянули. Может быть использовать не прямые формы, а какие-нибудь сложные, торчащие фигуры. В меню, например. upd Еще у вас есть грамматические ошибки на сайте, проверьте хорошенько тексты. Хорошо буду искать решение, за ошибки извиняюсь-исправляю. Сделать все на одной странице, подучить основы jQuery, и ajax для формы контактов. Главная страница слишком куцая, чтоб быть отдельной при таком дизайне. Спасибо, буду дорабатывать.
    1 point
  3. у всех аппаратов подобного типа есть один существенный недостаток - батарея! при относительно небольшой нагрузке, держит день, а с фильмами или музыкой - так вообще часа два...
    1 point
  4. Тут даже бенчмарки запускать не надо, чтобы это понять. var n = 0, l = elem.length - выполняется один раз n < l - сравнение двух примитивных значений n < elem.length - постоянное вычисление длины массива, а потом уже сравнение примитивных значений Разница очевидна
    1 point
  5. "Докотилось" - кошка рожала рожала, думала - "Ну все, больше не будет". И на тебе, взяла и "Докотилась" еще десятью котятами. Докатилось - правильный ответ.
    1 point
  6. Под этим- жирный такой +. Под этим тоже плюс, только уже не жирный. вот эти комментарии меня честно смутили. Я говорю не о конкретном проекте, а о подобных случаях в целом.А смутили не тем что, это по сути,тоже шаблон. Откуда- не знаю. А дело в том, что в таких случаях может быть очень много лишнего. Лишних блоков,как минимум. Т.е. Человек,начинает делать,подстраивать под свой сайт.Или подстраивать свой сайт под что. В итоге возникает такая вот дилемма: WTF? А,это наверное отступы.Сча поэкспериментирую.+5, -10. Все, понял, это точно отступ,ну,пусть будет 10рх. Такой то див.мм..Так, понятно, тут мне див не нужен,но пуская пока будет.Вдруг надумаю,чем заполнить этот блок. И т.п. В итоге получается что- #aside { float: right; color: #000; } только цвет и флоат. А приводит это к чему? Вот к чему. Я сейчас не обсуждаю тупо верстку, в которой я ни бум-бум. Я Трезво (подчеркиваю,ТРЕЗВО) оцениваю свои возможности. И говорю о том что, Символ символдраммы (ну,эта штучка,египетская) налезает на рамку рисунка. Думаю, Яркая поняла, о чем я говорю. Нужно капельку сдвинуть П.с. как и текст внутри #aside. П.п.с.- Уже 4 страницы
    1 point
  7. Кстати, не совсем соглашусь. Эта, как ты назвал "традиция" заложена во мне с детства, и поступали со мной так, не потому что они этого хотели, а потому что я сам это просил, относиться к моим работам со всей строгостью и высказывать мнения на счёт них по максимуму жёстко! Именно такими методами я начинал становиться на ноги и взрослеть. Адекватно размышляя над этим, я понял, что такой путь даст свои плоды (что и подтвердилось), а если всегда гладить по головке, то ни к чему хорошему это не приведёт. Это Имхо, я никому не навязываю, но действую так, потому что считаю это правильным. А вот эти вещи вообще считаю мусором и употреблять их в коде советую крайне редко, только когда это действительно необходимо. Отступы уже давно возложли на себя css, те же margin, padding, ну или line-height, если нужно между строчек.
    1 point
  8. Позволю себе добавить для всех споров про </br><br/> - прогрессивная часть человечества уже давно применяет простой короткий доктайп <!DOCTYPE html> в почти любых ситуациях. Ну на таких вот маленьких сайтах точно. А это означает что забываем о закрытиях и пишем просто <br>. То же касается и <img>. Возможно кто-то, кто живет в прошлом, будет со мной спорить, но это ерунда. XHTML - тупиковый период. Если мои слова ни для кого не авторитет, то просмотр исходного кода страниц Google все расставит по своим местам.
    1 point
  9. Svatov, а кто говорил про Такой подход? Речь о том, что бессмысленно браться за сложную задачу, не зная элементарщины. Все равно что пытаться прочесть роман, причем кому-то вслух, зная всего 10 букв алфавита. Практика это замечательно! Это реально ускоряет процесс обучения, Но надо же реально оценивать свои силы и практиковаться по мере изучения материала. Если у человека реальное желание, то его никто и ничто не отобьет, как до меня Макс написал. Тут по соседству есть тема, где присутствует яркое тому подтверждение.
    1 point
  10. Писал как-то мини-статейку.
    1 point
  11. В общем с фоном, через полупрозрачный пиксель надо делать. Вложенность дивов с уголками по желанию...но честно говоря я бы уже от таких решений отказывался бы и от поддержки старых браузеров..я так полагаю это еще с тех времен осталось. Если я правильно понял..вы брали пиксели вместе с подложкой (фон с шумом), а стоит просто взять пиксель с прозрачностью 50% как в макете, или задать через RGBA, с лучшей поддержкой кроссбраузерности лучше конечно вариант с полупрозрачным пикселем. Вот еще ...ссылка по поводу меню...вы используете старый вариант с мертвой зоной.
    1 point
  12. Сань, я не злая) просто считаю, что выставлять работу для поисков ошибок, надо не До того как изучил что-то, а хотя бы После того как внимательно выучил основы. А иначе в чем смысл? Yarkaya, успехов в обучении.
    1 point
  13. Ааа, ну ок, понял. Переубеждать не буду, моё дело предупредить)
    1 point
  14. Yarkaya, Ваш подход к учёбе изначально неверен и обречён на провал. Не беритесь за 10 дел сразу, а делайте всё последовательно, поэтапно. А вообще посоветовал бы вот что. Это план минимум!
    1 point
  15. И в итоге ни верстки, ни дизайна..
    1 point
  16. Тру, по поводу маргинов и паддингов: body.home #container { background: url("Natfon.jpg") repeat scroll 0 0 transparent; height: 719px; margin: 0 auto; width: 823px; } #header { color: #FFFFFF; font-size: 3.2em; padding: 10px; text-align: right; } Видимо, все же дошла. И вообще, какой смысл выставлять на суд работу, не выучив элементарных основ?
    1 point
  17. А чему вы учились две недели? Глава о доктайпе в Любой книге идет одной из первых. И где он? Пришла Алиска, все разнесла в пух и прах. Для двух недель еще более-менее прилично. К примеру еще вот такие сайты делают двухнедельные ученики.
    1 point
  18. А чему вы учились две недели? Глава о доктайпе в Любой книге идет одной из первых. И где он?
    1 point
  19. Мой совет - меньше прислушиваться к вышенаписанному бреду, больше делать то, к чему тянет. Я почитал Ваши рассуждения, почти под каждым готов подписаться. Как ни парадоксально, несмотря на то, что форум - сообщество непохожих людей, здесь большинство все же похожи, и в упор смотрят на "местные" стандарты. Верстка ужасна, но в целом картина выглядит куда приятнее, чем у многих местных с нулевым дизайном, отсутсвием логики, но отличной версткой (которую, кстати, проверять скучно из-за однотипных ошибок из других областей и штудированных элементов аспекта самой верстки). Чтобы не было уличений в слепости и прочих грехах, повторюсь - ошибок ворох, но это не верстка чьего-то шаблона с нарезанными пикчами, а самостоятельная работа. Оценивать одну лишь верстку в данном случае неправильно.
    -1 points
This leaderboard is set to Kiev/GMT+03:00
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy