Подтвердить что ты не робот

Является ли jQuery каким-либо кэшированием "селекторов"?

Например, будет ли первый фрагмент кода выполнять полный поиск дважды, или он достаточно умен, чтобы кэшировать результаты, если изменения DOM не произошли?

if ($("#navbar .heading").text() > "") {
  $("#navbar .heading").hide();
}

и

var $heading = $("#navbar .heading");

if ($heading.text() > "") {
  $heading.hide();
}

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

4b9b3361

Ответ 1

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

if ((cached = $("#navbar .heading")).text() > "") {
  cached.hide();
}

Даунсайд делает код немного более сложным и сложным.

Ответ 2

Всегда кешируйте свой выбор!

Расточительно постоянно вызывать $( selector ) снова и снова с помощью того же селектора.

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

var element = $("#someid");

element.click( function() {

  // no need to re-select #someid since we cached it
  element.hide(); 
});

Ответ 3

Это не столько вопрос "не так ли?", но "может это?", и нет, это невозможно - вы могли добавить дополнительные сопоставимые элементы в DOM с момента последнего запроса. Это сделало бы кэшированный результат устаревшим, и у jQuery не было бы (разумного) способа сказать, кроме запуска запроса снова.

Например:

$('#someid .someclass').show();
$('#someid').append('<div class="someclass">New!</div>');
$('#someid .someclass').hide();

В этом примере вновь добавленный элемент не будет скрыт, если будет какое-либо кэширование запроса - он скроет только те элементы, которые были обнаружены ранее.

Ответ 4

Я только что сделал метод решения этой проблемы:

var cache = {};

function $$(s)
{
    if (cache.hasOwnProperty(s))
    {
        return $(cache[s]);
    }

    var e = $(s);

    if(e.length > 0)
    {
        return $(cache[s] = e);
    }

}

И он работает следующим образом:

$$('div').each(function(){ ... });

Результаты являются точными, насколько я могу судить по этой простой проверке:

console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);

NB, он нарушит вашу реализацию MooTools или любую другую библиотеку, которая использует нотацию $$.

Ответ 5

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

Однако то, что вы делаете, не требует нескольких селекторов - это должно работать:

$("#navbar .heading:not(:empty)").hide();

Ответ 6

Как и ваш подход $$, я создал функцию (с тем же именем), которая использует шаблон запоминания для хранения глобального очистителя и также учитывает второй параметр контекста... например $$ ( ". class", "#context" ). Это необходимо, если вы используете цепочку find(), которая появляется после возврата $$; поэтому он не будет кэшироваться в одиночку, если вы сначала не кэшируете контекстный объект. Я также добавил логический параметр в конец (2-й или 3-й параметр в зависимости от используемого контекста), чтобы заставить его вернуться в DOM.

код:

function $$(a, b, c){
    var key;
    if(c){
        key = a + "," + b;
        if(!this.hasOwnProperty(key) || c){
            this[key] = $(a, b);
        }        
    }
    else if(b){
        if(typeof b == "boolean"){  
            key = a;  
            if(!this.hasOwnProperty(key) || b){
                this[key] = $(a);
            }
        }
        else{
            key = a + "," + b;
            this[key] = $(a, b);   
        }            
    }
    else{
        key = a;
        if(!this.hasOwnProperty(key)){
            this[key] = $(a);
        } 
    }
    return this[key]; 
}

Использование:

<div class="test">a</div>
<div id="container">
    <div class="test">b</div>
</div>​

<script>
  $$(".test").append("1"); //default behavior
  $$(".test", "#container").append("2"); //contextual 
  $$(".test", "#container").append("3"); //uses cache
  $$(".test", "#container", true).append("4"); //forces back to the dome
​
</script>

Ответ 7

Я не верю, что jquery выполняет кэширование селекторов, вместо этого опираясь на xpath/javascript под ним. что, как говорится, есть ряд оптимизаций, которые вы можете использовать в своих селекторах. вот несколько статей, которые охватывают некоторые основы:

Ответ 8

Этот $$() работает отлично - должен возвращать действительный объект jQuery в любом случае никогда undefined.

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

function $$(selector) {
  return cache.hasOwnProperty(selector) 
    ? cache[selector] 
    : cache[selector] = $(selector); 
};

И $$ может быть любым именем funciton, конечно.

Ответ 9

Джон Ресиг в своем интервью JQuery Internals в jQuery Camp 2008 упоминает о некоторых браузерах, поддерживающих события, которые запускаются при изменении DOM. Для таких случаев результаты Selctor могут быть кэшированы.

Ответ 10

Есть хороший плагин, который называется jQache, который делает именно это. После установки плагина я обычно делаю это:

var $$ = $.q;

А потом просто

$$ ( "# navbar.heading" ). hide();

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

$$ ( "# navbar.heading", true).hide();//сбрасывает кеш и скрывает новый (только что найденный) #navbar.heading

И

$$ ясно().//Полностью очищает кеш

Ответ 11

jQuery Sizzle автоматически кэширует последние функции, созданные из селекторов, чтобы найти элементы DOM. Однако сами элементы не кэшируются.

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

Ответ 12

jsPerf сегодня не работает, но в этой статье предполагает, что производительность, получаемая от кеширования селекторов jQuery, будет минимальной.

enter image description here

Это может быть просто к кешированию браузера. Проверенный селектор был только одним идентификатором. Дополнительные тесты должны быть выполнены для более сложных селекторов и различных структур страниц...

Ответ 14

Проверьте, помогает ли это https://plugins.jquery.com/cache/

Перешел через это как часть нашего обычного проекта