jQuery: что эффективнее? Множество специфичных для идентификаторов селекторов или один «Содержит префиксный селектор» - PullRequest
2 голосов
/ 01 декабря 2010

У меня есть фрагмент JavaScript в проекте, который кэширует массив объектов jQuery (тегов привязки) на панели инструментов:

$.extend(cache, {
    dashboard : {
        buttons : [
            $('#dash-new-lead'),               $('#dash-jobs-calendar'),
            $('#dash-view-lead'),              $('#dash-sales-reports'),
            $('#dash-search-leads'),           $('#dash-new-job'),
            $('#dash-dispatch-jobs'),          $('#dash-dispatch-reports'),
            $('#dash-manage-employees'),       $('#dash-manage-trucks'),
            $('#dash-finalize-jobs'),          $('#dash-payment-profiles'),
            $('#dash-employee-statements'),    $('#dash-company-statements'),
            $('#dash-finance-reports'),        $('#dash-admin-sources'),
            $('#dash-admin-statuses'),         $('#dash-admin-companies'),
            $('#dash-admin-groups'),           $('#dash-admin-users'),
            $('#dash-admin-dispositions'),     $('#dash-search-jobs'),
            $('#dash-jobs-calendar-dispatch'), $('#dash-new-lead-dispatch'),
            $('#dash-finance-notices')
        ]
    }
});

Каждая ссылка оформляется позже (используя $.each) в качестве кнопки,Каждая ссылка получает уникальный значок jQuery UI (отсюда и идентификаторы, а не просто селектор классов).В зависимости от уровня доступа пользователя некоторые ссылки могут или не могут существовать в DOM.

Теперь мне интересно, было бы более эффективно использовать jQuery Contains Prefix Selector :

$.extend(cache, {
    dashboard : {
        buttons : $('a[id|="dash-"]')
    }
});
  1. Pro: меньше ссылок на объект jQuery = быстрее
  2. Con: jQuery не может использовать document.getElementByID = медленнее

Ответы [ 4 ]

3 голосов
/ 01 декабря 2010

Вы можете сделать один селектор, который содержит все тождества:

$.extend(cache, {
  dashboard : {
    buttons : $('#dash-new-lead,#dash-jobs-calendar,#dash-view-lead,#dash-sales-reports,#dash-search-leads,#dash-new-job,#dash-dispatch-jobs,#dash-dispatch-reports,#dash-manage-employees,#dash-manage-trucks,#dash-finalize-jobs,#dash-payment-profiles,#dash-employee-statements,#dash-company-statements,#dash-finance-reports,#dash-admin-sources,#dash-admin-statuses,#dash-admin-companies,#dash-admin-groups,#dash-admin-users,#dash-admin-dispositions,#dash-search-jobs,#dash-jobs-calendar-dispatch,#dash-new-lead-dispatch,#dash-finance-notices')
  }
});

Однако я бы подумал о добавлении класса к кнопкам, чтобы их было проще нацеливать с помощью простого селектора. Это облегчило бы поддержку кода.

2 голосов
/ 24 апреля 2012

Так же, как каждый из ваших элементов имеет свой уникальный идентификатор (dash-new-jobs и т. Д.), Присвойте ему класс (class='dash-button').

После этого вы можете эффективно обратиться ко всей коллекции, например,

$.extend(cache, {
    dashboard : {
        buttons : $('.dash-button')
    }
});

И если вам нужно дать им все разные значки, как вы упомянули, используйте их уникальный идентификатор:

$('.dash-button').each(function() {
    // do something based on $(this).attr('id'),
    // which will be dash-new-job/dash-whatever
});

Эффективно (хотя, как уже говорили другие, проводите тесты производительности, если вы не уверены!), И чистый / легкий для понимания код (намного чище, чем использование селектора 'has'!).

2 голосов
/ 01 декабря 2010

Это будет сильно зависеть от браузера, поэтому вам нужно проверить, чтобы быть уверенным.

Поскольку 'a[id|="dash"]' (обратите внимание, я удалил -) , похоже, является допустимым селектором querySelectorAll(), любые браузеры, поддерживающие этот метод (включая IE8), должны иметь очень хорошую производительность.

Поскольку вы включаете tagName, браузеры, которые не поддерживают querySelectorAll(), будут (я считаю) использовать getElementsByTagName(), поэтому фильтр будет применяться только к элементам <a>, которые он найдет.

Это также должно помочь, если вы можете ограничить запрос более узким контекстом, чем document.

Также обратите внимание, что в соответствии с этим тестом , производительность getElementById() не очень впечатляет в IE6 и IE7. И снова IE8 поддерживает querySelectorAll(), хотя было бы неплохо убедиться, что он преуспеет с этим конкретным селектором. В противном случае запрос по умолчанию будет использовать движок Sizzle.


Вот тест с использованием этого селектора напрямую через querySelectorAll(). Вы можете запустить его в разных браузерах, чтобы увидеть, где он поддерживается.


Обратите внимание также, что getElementsByClassName() не поддерживается до IE9, поэтому я сомневаюсь, что использование класса предложит какие-либо существенные улучшения производительности по сравнению с 'a[id|="dash"]'. Исключением является Firefox3, который поддерживает getElementsByClassName(), а не querySelectorAll().

1 голос
/ 01 декабря 2010

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

Хотя метод id, скорее всего, будет иметь более высокую производительность, вы 'создает объект jQuery для каждого.Это тоже должно оказать влияние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...