jQuery для верстальщика (часть 2): вкусные меню

    Это вторая статья о jQuery, которая будет интересна, прежде всего, начинающим пользователям этой библиотеки. В этой статье, с практической точки зрения, речь пойдет о подсветке текущего элемента меню на стороне клиента. А прочитав статью, вы поймете, как делать более сложные выборки и цепочки запросов.


    Задача №2: вертикальное меню


    Меню – фундаментальный элемент пользовательского интерфейса, как GUI, так и веб-приложений. На нескольких небольших примерах мы посмотрим, как с помощью jQuery создать элемент навигации. К тому же изучим обещанные возможности функции $(…) по работе со свойствами элементов.

    Вертикальные меню представляют собой обычные списки ссылок:
    <ul>
    	<li><a href="/menu.html">Главная</a></li>
    	<li><a href="/articles.html">Статьи</a></li>
    	<li><a href="/forum.html">Форум</a></li>
    	<li><a href="/links.html">Ссылки</a></li>
    	<li><a href="/about.html">О нас</a></li>
    </ul>
    


    Его можно оформить очень красиво через таблицы стилей, и очень бы хотелось, что текущий раздел меню был подсвечен жирным шрифтом (или выделен как-то по-другому), чтобы дать пользователю понять, где он сейчас находится. Действовать можно по-разному: либо на стороне сервера, либо на стороне клиента. Серверный скрипт может при генерации страницы определить, какой пункт меню соответствует текущей странице, и пропишет нужный класс у элемента списка. У этого варианта есть недостатки: придется писать систему генерации меню на стороне сервера, при использовании же готовых скриптов трудно будет модифицировать модуль по работе с меню, а иногда возможность написания серверных скриптов отсутствует как таковая. Второй вариант лишен выше перечисленных недостатков. И для этого надо написать опять одну строчку в конструкции $(document).ready:

    $("a[@href$=" + document.location.pathname + "]").css({fontWeight: "bold"})
    


    Как вариант, можно использовать несколько другой подход, который предложил PaulColomiets:

    var a = $("a[@href$=" + document.location.pathname + "]");
    a.parent().text(a.text()).addClass('selected');
    


    PaulColomiets Справедливо замечает, что выбирать лучше не просто тег a, но и необходимо указать более полный путь до него.

    ayavryk

    Как это работает


    При изменении формата ссылок (я использовал относительные пути), необходимо будет поменять и скрипт. Что касается одной строчки, которая делает всю работу, то в ней используется уже знакомая функция $(…), которая в данном случае выбирает все ссылки с значением атрибута href, заканчивающегося на document.location.pathname. В этой переменной в свою очередь хранится путь до текущей страницы. Также мы используем метод css для установки значения параметра каскадных таблиц стилей font-weight. Если вы обратили внимание, то название параметра font-weight, написано немного по-другому fontWeight, то есть стилем «верблюд», который используется в JavaScript. В качестве завершающего штриха предлагаю сделать так, чтобы клик по элементу меню текущего раздела отменялся. Это очень разумное решение, ведь нельзя перейти на страницу, на которой уже находишься. А еще мне удастся продемонстрировать цепочку вызовов, которые постоянно используются в скриптах с jQuery:

    $(document).ready(function() {
    	$("a[@href$=" + document.location.pathname + "]")
    		.css({fontWeight: "bold"})
    		.click(function() { return false; } );
    });
    


    Выводы


    У нас получилось обойтись без дополнительных переменных, что сокращает код в простых случаях без ущерба ясности. В этом исходнике вы можете также посмотреть стиль оформления, который удачно подойдет в таком случае: вместо одной строчке, я бью цепочку вызовов на несколько, чтобы показать, где вызовы происходят. Я думаю, что теперь не составит труда изменить скрипт для прикрепления «стрелочки», только к внешним ссылкам. Очень рекомендую посмотреть для простоты, какие операторы эквивалентности есть кроме «$=», и что именно они делают.
    <p/>

    Цикл статей


    Комментарии 72

      0
      Мне кажется такого рода статьи разумно укомплектовывать работающими демонстрационными примерами
        0
        Спасибо за комментарий, но в статье приведен полностью весь код, за исключением, тегов html, head и тому подобное.
          +8
          я это и имею в виду) просто открыв такую статью мне в первую очередь хочется открыть результат и поклацать, посмотреть что получилось, а уже потом посмотреть как это получилось(если мне покажется интересен результат).
            0
            поддерживаю.

            а вообще, мне кажется, лучше завести домен-блог и ура и вперёд. сюда копипастить, статичные примеры скриншотить или ссылаться.
              0
              1000%!!!
              почти всегда ищу код для просмотра, а потом уже вникаю в смысл статьи если она меня как-то заинтересует.
                0
                тоесть ссылку для просмотра примерчика :)
          • НЛО прилетело и опубликовало эту надпись здесь
              –2
              Если бы сформулировали свой комментарий без полуматерной лексики, я бы вам ответил по существу.
                0
                Тем неменее крайне важное замечание.
                  0
                  Я написал, что не согласен с формой, а не содержанием. Возможно, кто-то выложит код для вырезания тега ссылки у текущей страницы - изменений требуется минимум :) Про вырезание тегов и очистку "html от ворда" я расскажу в другой статье - материал у меня по этому поводу есть.
                    +1
                    Ну вот примерно такой вариант мне кажется более приемлимым:

                    var a = $("a[@href$=" + document.location.pathname + "]");
                    a.parent().text(a.text()).addClass('selected');
                      0
                      Если не возражаете, я ваш комментарий утащу в пост. Спасибо.
                • НЛО прилетело и опубликовало эту надпись здесь
              –2
              А вот представьте, что ссылки в списке - это разделы, у которых есть свои подстраницы. И на этих подстраницах необходимо также выделять раздел (хотя урл ссылки на раздел, и урл текущей подстраницы будут отличаться). Вот поэтому Ваш способ слабо применим на практике.

              Статейка подойдет для ознакомления с селекторами в jQuery, но ни в коем случае как руководство к действию.

              Кстати, по поводу "выключения" текущей ссылки - то же самое, если нужно вернуться в раздел - то жмут обычно её.
                0
                Спасибо за комментарий. Но, пожалуйста, перечитайте статью - я в самом начале написал про условия: меню - список, про подразделы там ничего не говориться. Про разворачивающиеся меню у меня вроде есть материал - выложу.

                > Статейка подойдет для ознакомления с селекторами в jQuery, но ни в коем случае как руководство к действию.
                Цитирую статью: "А прочитав статью, вы поймете, как делать более сложные выборки и цепочки запросов."
                +1
                Если ты обратил внимание, то название параметра font-weight, написано немного по-другому fontWeight, то есть стилем «верблюд», который используется в JavaScript.

                Поясните, с какой целью так сделано.

                И еще. Начинается статья с обращения на "вы", а потом переходите на "ты". Неприятно.
                  0
                  Спасибо поправил.
                    0
                    Спасибо.

                    А по-поводу "fontWeight" поясните?
                      0
                      Пояснил, чуть ниже. :)
                    0
                    По поводу стиля верблюд, в JS насколько я знаю не используется символ дефис в идентификаторах.
                      0
                      Так здесь же описывается не идентификатор, а именно CSS-свойство. Надо писать его нормально.
                        0
                        Именно идентификатор, ведь это код на JS.
                          +1
                          Хм...
                          Если верить документации, то в таком варианте вы правы.

                          Я использую Visual jQuery в качестве документации, там это неочевидно.

                          Вариант .css({'font-weight': "bold"}) также работает, единственное, font-weight надо взять в кавычки (из-за дефиса).
                            0
                            Да это тоже вариант, рад что удалось прояснить ситуацию.
                              0
                              IMHO, раз уж Вы всё-равно несколько раз правили статью из-за комментариев, это тоже лучше изменить. Использование 'font-weight' значительно лучше, т.к. не вводит новых странных стилей требующих дополнительных комментариев "что есть верблюд и зачем он нужен".
                                0
                                Дело в том, что оба варианты равноценны. А по поводу правки статьи, я предпочитаю вносить в пост комментарии, которые дают что-то новое, точнее усовершенствование, а в комментах мы подробно обсудили, что есть "верблюд" (это, кстати, один из стандартных стилей именования идентификаторов) ;)
                    +1
                    Спасибо. Очень ясно и без воды объясняете. Надеюсь продолжите :-)
                      0
                      Да продолжу. разумеется.
                      +1
                      И не обращайте внимание на любителей выискивать ошибки. На самом деле, и так понятно что это примеры, удобные для понимания, к тому же, а не рекомендации к использованию.
                        0
                        Я очень положительно отношусь к критике, особенно конструктивной. Если человек пишет "это все лажа и фигня, я с закрытыми глазами делаю лучше", я просто не реагирую, а если пишет, что "лучше использовать такое-то свойство, вот ссылочка на пример", то я безусловно плюсую его.
                        0
                        а как быть, если урлы вроде /about/ ?
                        а если находимся на главной, т.е. нет никаких "menu.html"
                        то все ссылки жиром, пояните плиз..
                        Спасибо за статью! )
                          0
                          Спасибо за комментарий.
                          1) "При изменении формата ссылок (я использовал относительные пути), необходимо будет поменять и скрипт." Менять надо именно селектор.
                          2) Я не пробовал, но, по-моему, и в вашем случае будет работать, хотя я могу ошибаться.
                          0
                          спасибо! очень не хватало таких практических примеров
                            0
                            Полезно для изучения jQuery и абсолютно бессмысленно с точки зрения применения.
                            Вы пытаетесь почесать ухо левой ногой, иначе я не могу описать смысл клиентских манипуляций с меню.
                            Попробуйте мыслить категориями "документ", а не "веб-страничка". Документ должен быть понятен и без стилей, поэтому ссылки со страницы на саму себя и какие-то ухищрения с JS-выделением выглядят дико.
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                По поводу подсветки текущего пункта меню, это вопрос юзабилити, надо показывать пользователю, где он находиться и куда он может перейти.
                                • НЛО прилетело и опубликовало эту надпись здесь
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                Спасибо за конструктивный комментарий, я его украду. ОК?
                                0
                                Чтобы не просто сотрясать воздух: я вижу вам очень хочется что-то написать про jQuery и это правда здорово, но у вас большая проблема с примерами, они слишко надуманны и далеки от жизни.

                                Рискну подсказать один пример из того, что делал сам: выдайте пользователю ненумерованный список месяцов, разделённый запятыми и порубленный в четыре строки, по три месяца в каждой. Причём запятых в коде нет (семантика, ага) и для человеческих браузеров это будет CSS, а для IE и всех, кто не справится с CSS3, это будет скриптовая вставка.

                                Вот это будет увлекательно ;) Как думаете?
                                  0
                                  Отвечаю по порядку.
                                  1) Спасибо за конструктивный комментарий.
                                  2) Мне не хочется ничего писать про jQuery, статьи я писал в свое время для одного журнала, когда это библиотека только появилась, и по ней не было русских материалов вообще. В данный момент, я перерабатываю эти материалы, и выкладываю сюда, потому что люди заинтересовались.
                                  3) Проблем с примерами у меня нет - они все для обучения, причем последовательного, прочитайте, пожалуйста, первую статью, потом вторую, завтра послезавтра - третью.
                                  4) Что касается вашего примера, мне кажется, что он очень узкому кругу лиц. Опять же, как обучающий пример - он не очень годиться. Вы мне можете возратить, написав, небольшую заметку, где ваш пример подробно разберете и напишите соответствующий код. С удовольствием поставлю плюсик вашему топику.
                                  5) По поводу моих надуманности примеров, первый взят из небольшего и не очень известного сайта Википедия :) Второй (выделение текущего пункта меню) есть на многих сайтах и движках, но реализован на стороне сервера.
                                  6) В любом случае спасибо за конструктивную критику, ей я всегда рад.
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      –1
                                      jQuery('ul', context).css({'display': 'block', 'margin-left': '0px', 'padding-left': '0px'}).find('li').css({'display': 'inline', 'list-style': 'none', 'padding-left': '0px'}).end().find('li:nth-child(4n)').after('<br />').end().find('li:not(li:last)').after(',');

                                      Разве это увлекательно? Стоит ради этого писать отдельный пост :-)? А вообще претензии по существу — надоели уже статьи с пустяковыми примерами (автор, простите), хочется какого-нибудь «мяска» и побольше, побольше! Вроде бы название ресурса не «First Steps», здесь матёрые волчары в основном тусуются ;-)

                                        0
                                        Уважаемый господин "волчара"! У вас есть все возможности написать пост с "мясом", причем большой! Только вы почему-то данной возможностью пока не воспользовались.
                                          0
                                          кармы не хватает :)
                                            0
                                            а минусовать было не обязательно, можно было бы наоборт кармы подкинуть, чтобы дать мне возможность что-то написать :-P
                                              0
                                              Ваша карма позволяет писать в личный блог, напишите туда, если пост нормальный вам карму поднимут и вы перенесете его в тематический блог. Это стандартный путь для новичка.
                                                0
                                                кто ж будет его читать, личный-то блог…
                                                  0

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

                                                  (автор, простите)

                                                  ну да ладно, фиг с ней, с кармой… простите ещё раз, если обидел чем — не хотел, честно :)

                                                    0
                                                    Я вам отписал в приват и зафрендил, а по поводу кармы, я же сказал - пишите и вас оценят. Давайте оффтопик закончим, особенно учитывая что статье сто лет в обед.

                                                    ЗЫ "чукча, кстати, в большей степени читатель, чем писатель" - в этом-то и дело.
                                              0
                                              Эмм… Писать весь CSS в jQuery? Вот это мясо, не спорю…
                                                0
                                                ну понятно дело, что не весь, просто чтобы компактно воткнуть сюда :)
                                                  0
                                                  %) верю
                                                    0
                                                    кстати, проверил в IE, кривовато работает, вылилось так вот походу прямо в камент :)
                                            0
                                            так где можно посмотреть онлайн пример?
                                              0
                                              Господа, устал бороться. Подскажите, плз, новичку:

                                              имею длинную страницу div-ов с уникальными id. при вызове в середине страницы функции $(id).slideDown(600);
                                              вся страница передергивается и переносит пользователя в начало, при этом выполняя задачу.
                                              где грабли могут быть?
                                                0
                                                Селекторы работают по тем же правилам что и CSS, в Вашем случае необходимо писать так: $('#'+id).slideDown(600);
                                                  0
                                                  для начала было бы неплохо ознакомиться с документацией и понять, что jQuery !== Prototype
                                                  0
                                                  Ну а все-таки как если относительные ссылки?
                                                  Надо первый слэш обрезать..
                                                    +1
                                                    jQuery([brain, eyes]).each(function () { this.switchOn(); }); ? :-D
                                                      0
                                                      Что-то я не нашел описания не одной функции на сайте-прозводителе.
                                                      Вроде как "идем по всем элементам и переставляем местами"?
                                                      Или это вообще не к моему вопросу?)
                                                        0
                                                        это шутка :) означает дословно следующее: заполняем массив объектами «мозг» и «глаза», а потом проходимся циклом по элементам массива и для каждого элемента выполняем метод switchOn, т.е. "мозг"->"включить" и "глаза"->"включить", смысл всего этого: "включить мозг и глаза" :) блин, мне за мои шуточки карму в минус загонят…
                                                          0
                                                          Ага, вот оно как, хорошо хоть не в гугл =)
                                                          Ну а по существу-то?)
                                                    –1
                                                    Широко вошедшие в употребление в сфере интерфейсов слова "вкусные" и "богатые", символизируют новую эру в развитии интерфейсов или всего лишь беспомощность переводчиков и читателей?
                                                      0
                                                      Извините, вы кого имеете в виду под словом "переводчик"?
                                                        –1
                                                        Тех, кто первым тупо переносит слова, которые бездумно подхватывают другие, даже, в том числе, и не при переводе, а при написании собственных текстов.
                                                          –1
                                                          Извините, но вы бред откровенный пишите.
                                                            0
                                                            Я всего лишь выражаю своё скромное мнение, что словосочетание "вкусные меню" — блевотное.
                                                      0
                                                      очень жду продолжения цикла статей об этом JS-фреймворке!
                                                        0
                                                        а куда первую часть похерили?

                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                        Самое читаемое