jQuery для начинающих. Часть 4. Селекторы

Categories: JavaScript

Последнее время мне всё чаще задают вопрос как выбрать тот или иной элемент в DOM’е, и данный пост будет сплошь посвящен селекторам в jQuery, возможно большинство из них Вы видели в различных источниках, но собрать их воедино все же стоит…

Во всех примерах используется сокращенный вариант вызова jQuery методов, используя функцию $ (знак доллара)

Селекторы в jQuery базируются на CSS селекторах, а так же поддерживают XPath. Дабы не закапываться в документацию буду приводить примеры, много примеров. Но начнем с самых азов…

Для начала нам понадобиться макет HTML странички (вполне типичный макет):

<div id="header">
    <h1><a href="/" title="homepage">Title</a></h1>
    <h2>Sub-title <span>small description</span></h2>
</div>
<div id="wrapper">
    <div id="content">
        <div class="post">
            <h3>Post Title</h3>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
            <span>Image Title</span>
            <img src="/image1.jpg" alt="Image Alt Text"/>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
            <span class="inner-banner">Banner Text</span>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
        </div>
        <span id="banner"><img src="/banner1.jpg" alt="Big Banner"/></span>
        <div class="post">
            <h3>Post Title</h3>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
            <span>Image Title</span>
            <img src="/image2.jpg" alt="Image Alt Text"/>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
            <span class="inner-banner">Banner Text</span>
            <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed viverra tempus sapien.
               Cras condimentum, tellus id lacinia fermentum, tortor lectus tincidunt sapien,
               vel varius augue tortor vel tortor.</p>
        </div>
    </div>
</div>
<div id="sidebar">
    <ul>
         <li><a href="/item0.html">Menu Item 0</a></li>
         <li><a href="/item1.html">Menu Item 1</a></li>
         <li><a href="/item2.html">Menu Item 2</a></li>
         <li><a href="/item3.html">Menu Item 3</a></li>
    </ul>
</div>
<div id="footer">
    Copyright &copy; 2008
</div>

А теперь приступим к выборкам:

Выбор элементов по Id либо ClassName аналогично используемому в CSS

$('#sidebar');    // выбор элемента с id = sidebar
$('.post');       // выбор элементов с class = post
$('div#sidebar'); // выбор элемента div с id = sidebar
$('div.post');    // выбор элементов div с class = post

Примечание: используйте валидные имена классов и id

Бродим по иерархии объектов в DOM’е

Простой выбор потомков:

$('div span');            // выбор всех span элементов в элементах div

Аналогичный результат так же можно получить используя следующую конструкцию:

$('div').find('span');    // выбор всех span элементов в элементах div

Выбор только непосредственных потомков

$('div > span');          // выбор всех span элементов в элементах div, где span является прямым потомком div'a

Как же лучше поступить, что работает быстрее? Надо бы протестировать…

Так же селекторы можно группировать:

$('div, span');          // выбор всех div и span элементов

Поиск по соседям:

$('span + img');         // выбор всех img элементов перед которыми идут span элементы
$('span ~ img');         // выбор всех img элементов после первого элемента span
$('#banner').prev();     // выбор предыдущего элемента от найденого
$('#banner').next();     // выбор следующего элемента от найденого

Выбор всех элементов, всех предков, всех потомков

$('*');                // выбор всех элементов
$('p > *');            // выбор всех потомков элементов p
$('p').children();     // --
$('p').parent();       // выбор всех прямых предков элементов p
$('* > p');            // выбор всех предков элементов p (скорей всего Вам не понадобится)
$('p').parents();      // --
$('p').parents('div'); // выбор всех предков элемента p которые есть div (parents принимает в качестве параметра селектор)

Фильтры

Фильтров в jQuery реализовано достаточно много, и пользоваться ими одно удовольствие:

$('div:first');     // выбираем первый div в доме
$('div:last');      // выбираем последний div в доме
$('div:not(.red)'); // выбираем div'ы у которых нету класса red
$('div:even');      // выбираем четные div'ы
$('div:odd');       // выбираем нечетные div'ы
$('div:eq(N)');     // выбираем div идущим под номером N в DOMe
$('div:gt(N)');     // выбираем div'ы, индекс которых больше чем N в DOMe
$('div:lt(N)');     // выбираем div'ы, индекс которых меньше чем N в DOMe
$(':header');       // выбо заголовоков h1, h2, h3 и т.д.
$('div:animated');  // выбор элементов с активной анимацией

Фильтры по контенту и видимости:

$('div:contains(text)'); // выбираем div'ы содержащие текст
$('div:empty');          // выбираем пустые div'ы
$('div:has(p)');         // выбираем div'ы которые содержат p
$('div.red').filter('.bold') // выбираем div'ы которые содержат класс red и класс bold
$('div:hidden');         // выбираем скрытые div'ы
$('div:visible');        // выбираем видимые div'ы

Так же есть фильтры по атрибутам:

$("div[id]");           // выбор всех div с атрибутом id
$("div[title='my']");   // выбор всех div с атрибутом title=my
$("div[title!='my']");  // выбор всех div с атрибутом title не равного my
$("div[title^='my']");  // выбор всех div с атрибутом title начинающихся с my
                        // <div title="myCat">,<div title="myCoffee">, <div title="my...">
$("div[title$='my']");  // выбор всех div с атрибутом title заканчивающихся на my
                        // <div title="itsmy">,<div title="somy">, <div title="...my">
$("div[title*='my']");  // выбор всех div с атрибутом title содержащим my
                        // <div title="itsmy">,<div title="myCat">, <div title="its my cat">,<div title="...my...">

так же стоит отдельно отметить следующий фильтр:

$("a[rel~='external']"); // выбор всех A с атрибутом rel содержащим external в списке значений разделенных пробелом
</code>
В результате его работы будут выбраны следующие теги:
<code lang="HTML4strict">
<a href="" rel="external">link</a> — да
<a href="" rel="nofollow external">link</a> — да
<a href="" rel="external nofollow">link</a> — да
<a href="" rel="friend external follow">link</a> — да
<a href="" rel="external-link">link</a> — нет

Для работы с элементами форм есть ряд селекторов позволяющий выбирать по типу элемента и фильтров – enabled/disabled/selected/checked :

$(":text");            // выбор всех input элементов с типом =text
$(":radio");           // выбор всех input элементов с типом =radio
                       // и так далее
$("input:enabled");    // выбор всех включенных элементов input
$("input:checked");    // выбор всех отмеченных чекбоксов

Фильтры так же можно группировать:

$("div[name=city]:visible:has(p)"); // выбор видимого div'a с именем city, который содержит тег p

Приведу так же ряд полезных селекторов для работы с элементами форм:

$("form select[name=city] option:selected").val(); // получение выбранного(-ых) элементов в селекте city
$("form :radio[name=some]:checked").val(); // получение выбранного значения радиобатона с именем some
$("form :checkbox:checked"); // выбор всех выбранных чекбоксов

Еще советую почитать статью jQuery: 8 полезных советов при работе с элементом SELECT

Если Вам хочеться опробывать как это все работает – то для этого можете воспользоваться тестовой страничкой

Слайды

Как-то слишком много текста получилось, пожалуй пора показывать слайды ;)



jQuery: Simple HTML structure
jQuery: Select by Class or Id
jQuery: Hierarchy
jQuery: Hierarchy
jQuery: Basic filters
jQuery: Basic filters 2
jQuery: Attribute filters
jQuery: Traversing
jQuery: HTML and TXT methods
jQuery: Manipulation - prepend and append
jQuery: Manipulation - insert
jQuery: Manipulation - wrap
jQuery: Manipulation - empty and remove
jQuery: Manipulation - replace

Данная статья написана с использованием следующих ресурсов:

Цикл статей

  1. jQuery для начинающих
  2. jQuery для начинающих. Часть 2. JavaScript Меню
  3. jQuery для начинающих. Часть 3. AJAX
  4. jQuery для начинающих. Часть 4. Селекторы

This entry was posted on Wednesday, January 28th, 2009 at 08:25 and is filed under JavaScript.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Другие посты на эту тему

38 Responses to “jQuery для начинающих. Часть 4. Селекторы”

  1. [...] jQuery для начинающих. Часть 4. Селекторы Tags: AJAX, jQuery | October 8th, 2008 | 13,281 views [...]

  2. А с выходом jQuery 1.3 изменилась поддержка селекторов? Это же вроде основная часть где есть изменения между 1.2 и 1.3.

    PS: К слову о селекторах: http://blog.jquery.com/2008/10/28/jquery-pumpkin/ =)

  3. @EvilFaeton:
    Принцип работы селекторов не изенился, ибо он основывается на CSS3 – были оптимизирована их работа – это да, да еще был добавлен event live – который отслеживает изменения в DOM’е и вешает соответствующие обработчики на новые элементы…
    Более подробно можно почитать на домашней страничке проекта Release: jQuery 1.3

  4. Нет,я про это:

    Селекторы в jQuery базируются на CSS селекторах, а так же поддерживают XPath.

    Насколько я помню бета версия 1.3 с селекторами xPath не дружила, в финальной версии, он xPath поддерживает?

  5. omfg

    Давно читаю ваш блог и посты про jquery всегда в закладках валялись, так как плотно с ним сталкиваться не приходилось. И вот буквально на днях пришлось реализовывать сложное меню, прочитал два первых урока и все получилось, спасибо!

    За эту статью тоже большое спасибо, но тут, слава богу знаний о селекторах достаточно) Очень хотелось бы увидеть статью про события, надеюсь она у вас в задумках ;)

  6. Есть еще 2 вида селекторов атрибутов:

    $("a[rel~='external']"); // выбор всех A с атрибутом title содержащим my в списке значений разделенных пробелом

    rel="external" — да
    rel="nofollow external" — да
    rel="external nofollow" — да
    rel="friend external follow" — да
    rel="external-link" — нет

    $("a[hreflang|='en']"); // выбор всех A с атрибутом hreflang начинающемся на en в списке значений разделенных дефисом

    hreflang="en-us" — да
    hreflang="en-en" — да
    hreflang="us-en" — нет

    Первый способ нормально работает в jQuery, а вот второй в версии 1.3.1 вроде не правильно, но код, обрабатывающий селектор такого вида точно есть :)

    А еще в статье нет упоминания о том, что можно группировать селекторы атрибутов:

    $("a[hreflang|='en'][rel~='external']")

    и использовать составные селекторы:

    $("#sidebar, .post")

  7. Guzel


    $("form :radio[name=some]:selected").val();// получение выбранного значения радиобатона с именем some

    Здесь небольшая ошибка. Вместо selected должно быть checked.

  8. Денис

    $("a[rel~='external']"); // выбор всех A с атрибутом title содержащим my в списке значений разделенных пробелом

    Наверное все таки A с атрибутом rel

    Спасибо за хорошую подборку в одном месте и за удобные слайды, можно было бы их еще скачать в шпаргалку ;)

  9. Sergio

    Антон, после фичи СЛАЙДЫ я окончательно стал Вашим поклонником =)
    Очень редко в интернете встретишь людей, которые на доступном языке и с применением хороших методов обучения (слайды,примеры,практика,дискуссия) умеют объяснять суть. Спасибо за Ваше желание создавать кладези грамотной инфы, не перенасыщенные лишним контентом.

    Антон, у меня как раз есть вопрос на счет обращения к элементу. Мне необходимо узнать реальную ширину и длину изображения.jpg Пробовал пользоваться функциями Height.. , но они показывают данные о размерах, заданных в CSS.

    P.S. Подскажите, пожалуйста, какой программой Вы создаете эти слайды? Мне она очень поможет, я обладаю похожими с Вами качествами объяснять людям и делаю это постоянно, но вот средств не хватает, программных средств.

    • Насчет получения размера изображение – $(‘img’).attr(“width”) …

      Слайды создавались с помощью фотошопа – минута на слайд – не так уж и много :) Слайдшоу сделано с помощью плагина (a) Slideshow

  10. Дякую, за статтю, хоча біля 90% було мені відомо, все одно цікаво почитати.
    А слайди – то взагалі бомба.

  11. Sergio

    хм, почему то у меня $(’#id’).attr(”width”) … выдает значение 0. Как только не провобыл извлечь размер изображения, результат всё тот же: вместо реальных значений ширины и высоты (разрешения изображения) выдаются значения ширины и высоты, заданные в для самого элемента страницы (например, в коде css).

    В чем может быть дело?

    P.S.
    А вот $(’#id’).attr(”src”)… действительно выдает имя файла с изображением, здесь всё правильно срабатывает.

    • Якщо в рисунка не заданий атрибут width – то jQuery нічого не поверне, бо вона не тягне ширину зображення з сервера, а тягне з атрибутів (а атрибут src завжди потрібно задавати, на відміну від ширини).

  12. [...] Антон Шевчук пишет мануал по jQuery, если ман не был настолько дотошным я бы даже не обратил на него внимания jQuery для начинающих. Часть 4. Селекторы [...]

  13. [...] jQuery для начинающих. Часть 4. Селекторы March 3rd, 2008 | 100,802 views | Tags: JavaScript, jQuery [...]

  14. Sergio

    Отвечаю сам.
    Выход я нашел только один, т.к. в языке судя по всему не предусмотрены такие тривиальные вещи, …
    Итак,
    var hugeimage=new Image();
    hugeimage.src=currentsrc+”.jpg”;
    cc=hugeimage.width;
    dd=hugeimage.height;

    Переменные cc и dd теперь можно использовать при задании размеров изображения:

    $(“#enlargedimage”).css({width: cc, height: dd, opacity: “1.0″}); /* показать картинку на экране монитора в натуральную величину */

  15. Sergio

    Если у вас код достаточно простой, то возможно он позволит поступить ещё проще:

    Просто не задавайте нигде размеров увеличенного изображения (того, что будет показываться при клике на маленькое изображение) – ни в тэге img (в моем случае он имеет id=enlargedimage), ни в css, ни функциями Height(здесь размер в пикселях) и Width(здесь размер в пикселях).
    Тогда при загрузке увеличенного изображения браузер сам определит необходимые ширину и высоту для этого изображения,и они будут равняться реальным ширине и высоте изображения (его разрешению).

  16. @Sergio:
    $(“#id”).attr(“width”) действительно работает только в том случае если размер не задан ни через CSS, ни через атрибуты…

  17. Толковая, подробная статья, спасибо.

    Только конструкции типа

    div:first

    и

    div:last

    , наверное, правильнее все-таки, называть не фильтрами, а псевдоклассами.

    CSS-фильтрами обычно называют:
    CSS-спецэффекты от Микрософт, такие как тень, отражение и пр.
    Или CSS-хаки — селекторы, срабатывающие только в определенных бразуерах, например

    * html

    для IE.

  18. Антон скажи пожалуйсто что такое .siblings попроще и поподробней, совсем непойму что-то..

  19. Книжку достал jQuery in Action, интересно достаточно.

  20. [...] jQuery для начинающих. Часть 4. Селекторы August 6th, 2008 | 30,148 views | Tags: jQuery [...]

  21. Антон, ты наверняка работал с jQuery tools. Я только новичок, и мне необходима помощь толковых программистов.
    Вот здесь (http://flowplayer.org/tools/demos/overlay/external.html) описана функция:

    $(function() { 
    
     // if the function argument is given to overlay, it is assumed to be the onBeforeLoad event listener
     $("a[rel]").overlay(function() { 
    
     // grab wrapper element inside content
     var wrap = this.getContent().find("div.wrap"); 
    
     // load only for the first time it is opened
     if (wrap.is(":empty")) {
     wrap.load(this.getTrigger().attr("href"));
     }
     });
    });

    При этом для селектора можно задать параметры:

    $(function() {
    
        $("a[rel]").overlay({ 
    
            // custom expose settings
            expose: {
                color: '#BAD0DB',
                opacity: 0.7
            }
        });
    });
    

    А можно ли их объединить? То есть чтобы в работе первой функции учитывались параметры второй?

  22. Насколько я помню:

    $("a[rel]").overlay(function() {
      // ...
    });
    

    Аналогично записи:

    $("a[rel]").overlay({onBeforeLoad:function() {
      // ...
    }});
    

    Т.е. callback функцию передавайте в качестве параметра onBeforeLoad…

  23. Aderba

    Здравствуйте, может не в ту тему пишу, но очень надеюсь на вашу помощь!
    У меня такая проблемка, мне нужно узнать загружен ли iframe или нет, т.е. сработало у него событие onLoad …..
    Для чего мне это надо …..
    У меня есть строки в таблице, которые я могу редактировать посредством ajax ….. А вот сохранение происходит через iframe, чтобы не перегружать страницу. Допустим я несколько записей открыла для редактирования и хочу их всех сразу сохранить. Нажимаю на кнопку сохранить все и вызываю функцию saveAll(form) в которой делаю следующее: перебираю все ссылки, начинающиеся с слова save_ и вызываю обработчик на onclick

    $('a[@id^=save_]').each(function()
    {
        $(this).click();
    });
    

    Сам обработчик навешивается на событие в другом участке кода так

    /* save icon click handler */
    $('a[@id=save_'+id+']').click(function()
    {
    	inlineObject.submitInputContent(id, key, "edit");
    	UnblockRecordInline(inlineObject.edit_link,key,id);
    });
    

    Получается что для каждой записи вызывается функция submitInputContent, которая делает сабмит формы в iframе, а потом этот iframe удаляется.
    И вот мне нужно как то узнать загружены ли в iframe данные после сабмита или нет. Суть всего этого следующая, что если хоть одна из записей после сабмита вернула ошибку то я делаю один код, если нет, то другой …..

    • К сожалению, я не совсем понял решаемую задачу, но насчет загрузки iframe – это отслеживается следующим образом:

      $('iframe').ready(function() {
        $('body', $('iframe').contents()).html('Hello World!');
      });
      

      Но у меня сложилось впечатление, что использование фреймов в данном случае неверно – лучше уж использовать AJAX

  24. Dmitry

    Скажите, а как выбрать в div другой div с id=test, а в нём изображение?

    <div class="wrap">
      <div id="test">
       <img ..../>
      </div>
    </div>

    так верно?

    ...
    this.getContent().find("div.wrap #test img[title]")
    ...
  25. Eldar

    Есть таблица, в ней кнопки и спэны:

    <td><button id="btn1">Click Me</button></td>
    <td><span>Нужный текс</span></td>
    

    Как при обработке нажатия на кнопку получить доступ к тексту спэна?

    Я уже запутался с parent, child и sibling Ж(

  26. Надо изменить ссылку на XML-файл при загрузке документа

    <link
     id="os"
     rel="search"
     type="application/opensearchdescription+xml"
     href="http://transcriptor.ru/transcription/pinyin-russian/plugins/os-ie.xml" />
    <script type="text/javascript">
    <!--//--><![CDATA[//><!--
    $("#os").attr({href,"http://transcriptor.ru/transcription/pinyin-russian/plugins/os.xml"});
    //--><!]]>
    </script>

    Подскажите, почему не работает?

  27. Небольшая ошибка в синтаксисе, должно быть:

    $("#os").attr("href", "http://transcriptor.ru/transcription/pinyin-russian/plugins/os.xml");
    // либо
    $("#os").attr({href:"http://transcriptor.ru/transcription/pinyin-russian/plugins/os.xml"});
    
  28. Хм, почти та же ошибка, что и у NASA, когда они потеряли спутник.

    Спасибо, вроде все заработало. Правда, вылез другой баг уже связанный с браузером. :(((

  29. Sergey

    Здравствуйте! Хочу попросить вашей помощи в одном вопросе.

    У меня есть код:

    $(document).ready(function()
    {
    $(‘#timeval’).text = ”;

    var refreshId = setInterval(function()
    {
    $(‘#timeval’).load(‘/ajax/refresh/’+ Math.random());

    }, 4000);

    });

    Он подгружает каждые 4 секунды вывод php-странички.
    Все прекрасно, только вот никак не смог отыскать в интернете, как сделать так, чтобы при получении текста , начинающегося с
    “done” , обновление страницы бы прекращалось.

    ( в интернете нашел, что обновление странички останавливается с помощью clearInterval(refreshId); )

    Интересует сама возможность определить регулярным выражением, что пришедший текст начинается с “done”.

    Подскажите решение, если не трудно

    • Sergey

      Все спасибо, разобрался.

      сделано конечно по извращенному, но тут сроки поджимают.
      Может кому пригодится

      var txt = $(‘#timeval’).attr(‘innerHTML’);

      далее , preg_match’ем по txt ищем строку.

  30. htorrent

    Статья суперская! Поэтому подумал, может тут кто-нибудь поможет с моей проблемкой.

    Еще раз поднимаю тему-вопрос о картинках.

    Проблема: не все браузеры показывают реальные размеры изображения. IE – показывает, GoogleChrome – нет.

    
    $(document).ready(function(){
    
       //Создаем строку (две картинки).
       var stroka = "";
       stroka += "<img id='pics1' src='pics/101-02-01.jpg'>";
       stroka += "<img id='pics2' src='pics/101-02-02.jpg'>";
    
       //Вставляем строку в <div id='forlink5'></div> .
       $('#forlink5').html(stroka);
    
       //Перечисляем всех деток ('img') у элемента 'forlink5'
       //и смотрим какие у них размеры ('w' и 'h').
       $('#forlink5').find('img').each(function(i){
          var w = $(this).width();
          var h = $(this).height();
          var src = $(this).attr("src");
          alert("W="+w+", H="+h+", SRC="+src);
       });
    
    });
    

    Читал на других форумах, что мол картинка може уже находится в кеше и т.д. и т.п. Говорю сразу… это я уже проходил.

    Нужен вариант, чтобы определения размера картинки не зависело от наличия кеша и/или картинки в нем.

    Вариант получения размера при помощи PHP тоже не подходит.

    Решение должно быть в рамках JavaScript (и jQuery).

Leave a Reply

Copyright © 2007-2010, Anton Shevchuk. Powered by WordPress

MAXCACHE: 0.29MB/0.00041 sec