Это:
document.getElementById(selectElements[i].id) != ""
неправильно. Вы хотите проверить, имеет ли элемент идентификатор, поэтому просто выполните:
selectElements[i].id != ""
Я хотел бы отметить, что вы можете улучшить свой код здесь и там:
1 Не записывать for
циклов, которые получают свойство length
для каждой итерации,
вместо этого:
for( i = 0, num = selectElements.length; i < num; i++ ) {
...
}
Только если вы ожидаете, что selectElements
будет расти или уменьшаться, имеет смысл запросить значение свойства, но в этом случае вам, вероятно, все равно не следует писать цикл for
.
2: не писать nodelist[index]
Для нодлистов, таких как возвращаемые getElementsByTagName()
, вы не должны писать nodelist[index]
(даже если большинство браузеров поддерживают это). Стандартный метод DOM - item
, поэтому вместо него пишите nodelist.item(index)
.
3 выборки предметов из списка только один раз
Если вам нужен элемент из списка более одного раза, сохраните его в локальной переменной. ваш цикл станет:
for( i = 0, selectElement; i < selectElements.length; i++ ) {
selectElement = selectElements.item(i);
...more code using selectElement...
}
Обратите внимание на объявление переменной selectElement
в цикле for. так как вы не используете его вне цикла, его объявление избегает беспорядка и гарантирует, что если вы переместите цикл, вы переместите объявление.
4. сначала самые дешевые сравнения
Вы писали:
selectElement.className == "jumpmenu" &&
selectElement.id != ""
это можно было бы немного улучшить, если поменять ноги:
selectElement.id != "" &&
selectElement.className == "jumpmenu"
Это будет быстрее, так как проверять, пуста ли строка, меньше работы, а в тех случаях, когда строка пуста, мы даже не проверяем className
5 Не используйте document.getElementById()
, если у вас уже есть элемент
Внутри цикла у вас есть это:
jumpmenu = document.getElementById(selectElements[i].id);
В основном вы получаете идентификатор из selectElement
и используете его для запроса документа, чтобы найти .... элемент, имеющий и id
равный значению текущего selectElement
. Поскольку id
уникальны в документе (или должны быть), вы в основном пишете совершенно ненужное предложение. jumpmenu
и selectElement
относятся к одному и тому же объекту.
6. Улучшения обработчика onchange
внутри цикла вы назначаете обработчик onchange. Вы делаете это, создавая новую функцию для каждой итерации цикла. Это код обработчика:
function() {
if( this.options[this.selectedIndex].value != '' ) {
// Redirect
location.href=this.options[this.selectedIndex].value;
}
}
Здесь следует отметить три вещи: во-первых, код обработчика onchange содержит это location.href = ...
, которое, вероятно, должно быть document.location.href = ...
.
Во-вторых, вы дважды ссылаетесь на this.options[this.selectedIndex].value
. Опять же, поместите это в локальную переменную.
В-третьих, this
относится к элементу, который испытал событие onchange к моменту выполнения этой функции. Кроме this
и свойств this
, в этом обработчике нет переменных, которые бы исходили из цикла или внешней функции initJumpMenus
. Вы должны просто создать его один раз вне цикла и назначать его для каждой итерации:
var onchange_handler = function() {
if( this.options[this.selectedIndex].value != "" ) {
// Redirect
location.href=this.options[this.selectedIndex].value;
}
}
for (...) {
if (...) {
selectElement.onchange = onchange_handler;
}
}
7 Резюме
Сложив все это вместе, я бы так написал:
function initJumpMenus() {
var handler = function() {
var value = this.options.item(this.selectedIndex).value;
if( value != "" ) {
// Redirect
document.location.href = value;
}
}
var selectElements = document.getElementsByTagName("select");
for(var i = 0, num = selectElements.length, selectElement; i < num; i++ ) {
selectElement = selectElements.item(i);
// Check for the class and make sure the element has an ID
if( selectElement.id != "" &&
selectElement.className == "jumpmenu"
) {
selectElement.onchange = handler;
}
}
}