Должен ли я кэшировать document.getElementById() в переменной или вызывать ее каждый раз?

У меня много элементов, которые генерируются и ссылаются (наведение курсора, клики, изменения положения) много раз.

У меня есть идентификатор этих элементов. Целесообразно ли хранить вызовы document.getElementById(ID) в переменной, или это быстрее/так же быстро/медленнее, чтобы вызывать document.getElementById() каждый раз?

var app = [];
var app.elements = []; 
//i can store ['id1', 'id2', 'id3']
//OR ['id1' => document.getElementById('id1'), 'id2' => document.getElementById('id2'), 'id3' => document.getElementById('id3')]

Ответ 1

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

Пример:

var e1 = document.getElementById('id1');
e1.innerHTML = 'test';
e1.className = 'info';

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

// This will recreate all elements inside the 'parent' element:
document.getElementById('parent').innerHTML += 'test';

Ответ 2

getElementById возвращает элемент node, который по существу является только объектом JavaScript. Вы можете назначить этот объект переменной, означающую, что переменная будет указывать на этот объект всякий раз, когда вы вводите эту переменную на более позднем этапе. Таким образом,

var id1 = document.getElementById('id1');

id1 теперь относится к элементу DOM с id of id1. Если ни один элемент не был найден с этим id, то document.getElementById возвращает null.

Если элементы остаются внутри DOM и не заменяются, имеет смысл хранить их в массиве, поэтому вы можете ссылаться на них столько раз, сколько хотите, без каких-либо затрат на производительность.

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

function getElementsByIds( /* id1, id2 ... */ ) {

    var elems = [];

    for (var i = 0, l = arguments.length; i < l; i++) {
        elems[i] = document.getElementById(arguments[i]);
    }

    return elems;

}

app.elements = getElementsByIds('id1', 'id2', 'id3');

Ответ 3

Нет единого правильного ответа на этот вопрос. Все зависит от того, с чем вам приходится работать. Если вы работаете со страницей с большим количеством элементов в дереве DOM, лучше кэшировать ссылки и повторно использовать их, чтобы ускорить время поиска. Если вы работаете на небольшой странице, вам лучше искать элементы "на лету" и минимизировать потребление памяти браузером.

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

Многие современные фреймворки будут кэшировать элементы, которые вы нашли для себя. Тем не менее, я лично предпочитаю использовать document.getElementById большую часть времени. То, что я делаю, когда мне нужно кэшировать значения поиска, является следующее:

 function registerElement(id)
 {
     if (!this["get_" + id])
        this["get_" + id] = function() {
            var element = document.getElementById(id);
            this["get_" + id] = function() {return element;};
            return element;
        }
 }

Вы используете это, вызывая registerElement и передавая ему идентификатор элемента. Когда вам нужно получить значение, вы вызываете идентификатор get_element, который вы передали, и при первом запуске он будет искать элемент и кэшировать его, при каждом последующем вызове он просто возвращает кешированное значение.

Ответ 4

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

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

theMainButton.style.color = "red";
// vs.
document.getElementById("theMainButton").style.color = "red";