2015-01-22 3 views
0

Я отбросил jquery около 9 (иш) месяцев назад и нуждался в механизме выбора (без всяких хлопот и не против, т. Е. Поддержка < 7) поэтому я сделал упрощенную версию document.querySelectorAll, создавая эту функцию:Использование querySelectorВсе, чтобы получить ВСЕ элементы с этим именем класса, а не только первые

// "qsa" stands for: "querySelectorAll" 
window.qsa = function (el) { 
    var result = document.querySelectorAll(el)[0]; 
    return result; 
}; 

Это отлично работает на 95% от времени, но я имел эту проблему на некоторое время теперь, и я исследовал MDN, w3c , SO и не забывать Google :), но еще не нашли ответа, почему я только получил первый элемент с запрошенным классом. И я знаю, что только первый возвращаемый элемент вызван «[0]» в конце, но функция не будет работать, если я удалю его, поэтому я попытался создать цикл for с индексной переменной, увеличение стоимости в зависимости от длины элементов с этим классом, как это:

window.qsa = function (el) { 
    var result, el = document.querySelectorAll(el); 
    for(var i = 0; i < el.length; ++i) { 
    result = el[i]; 
    } 
    return result; 
}; 

Again, которые не работали, поэтому я попробовал время цикл, как это:

window.qsa = function (el) { 
    var result, i = 0, el = document.querySelectorAll(el); 
    while(i < el.length) { 
    i++; 
    } 
    result = el[i]; 
    return result; 
}; 

в настоящее время я начинаю интересно, что-нибудь работает? и я очень расстраиваюсь document.querySelectorAll ... Но мое упрямое внутреннее «я» продолжает идти, и я продолжаю терпеть неудачу (цикл цикла), поэтому я знаю, что сейчас НАСТОЯЩИМ время задать следующие вопросы:

Почему он возвращает только первый элемент с этим классом, а не все?

Почему мой цикл петли не работает?

Почему мой цикл while не работает?

И спасибо, потому что любая/вся помощь очень ценится.

+0

Как она используется? –

+1

Почему не только используется 'return document.querySelectorAll (el)'? –

+0

Проблема, безусловно, в том, где вы ее используете. Удаление [0] вернет NodeList элементов, а не один элемент, поэтому вам просто нужно рассматривать его как массив при обращении к элементам. –

ответ

1

Вы возвращаете один элемент. Вы можете вернуть массив. Если вы хотите иметь возможность воздействовать на все элементы сразу, стиль jQuery, вы можете передать обратный вызов в свою функцию;

window.qsa = function(query, callback) { 
 
    var els = document.querySelectorAll(query); 
 
    if (typeof callback == 'function') { 
 
     for (var i = 0; i < els.length; ++i) { 
 
      callback.call(els[i], els[i], i); 
 
     } 
 
    } 
 
    return els; 
 
}; 
 

 

 
qsa('button.change-all', function(btn) { 
 
    // You can reference the element using the first parameter 
 
    btn.addEventListener('click', function(){ 
 
     qsa('p', function(p, index){ 
 
      // Or you can reference the element using `this` 
 
      this.innerHTML = 'Changed ' + index; 
 
     }); 
 
    }); 
 
}); 
 

 
qsa('button.change-second', function(btn) { 
 
    btn.addEventListener('click', function(){ 
 
     var second = qsa('p')[1]; 
 
     second.innerHTML = 'Changed just the second one'; 
 
    }); 
 
});
<p>One</p> 
 
<p>Two</p> 
 
<p>Three</p> 
 

 
<button class='change-all'>Change Paragraphs</button> 
 
<button class='change-second'>Change Second Paragraph</button>

Тогда вы можете позвонить или использовать обратный вызов

qsa('P', function(){ 
    this.innerHTML = 'test'; 
}); 

Или вы можете использовать массив, возвращаемый

var pList = qsa('p'); 
var p1 = pList[0]; 
+0

Огромное вам спасибо за такой замечательный awnser отлично работает и спас меня от размера файла, а стиль кода отличный, если бы я мог бы увеличить миллион раз :-) – Malik

3

Почему это только возвращает первый элемент с этим классом, а не все из них?

Поскольку вы явно получаете первый элемент от результатов и возвращаете это.

Почему мой цикл петли не работает?

Поскольку вы перезаписываете result с новым значением каждый раз, когда вы идете по контуру цикла. Затем вы возвращаете последнее, что получаете.

Почему мой цикл while не работает?

По той же причине.


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

return document.querySelectorAll(el) 

Это даст вам NodeList объект, содержащий все элементы.


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

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

Это не элемент. Это NodeList, который похож на массив.

Если вы хотите, например, изменить цвет фона элемента, который вы могли бы сделать это:

element.style.backgroundColor = "red"; 

Если вы хотите изменить цвет фона каждого элемента в NodeList, то вы должны изменить цвет фона каждый в свою очередь: с петлей.

for (var i = 0; i < node_list.length; i++) { 
    var element = node_list[i]; 
    element.style.backgroundColor = "red"; 
} 
+0

Или 'window.qsa = document.querySelectorAll.bind (document);' но я предполагаю, что OP хотел бы сделать 'qsa ('p .something'). ClassList.add ('my-class')' –

+0

Thank вы для великого углубляющегося ящика я понимаю его еще много. – Malik

1

Этот цикл

for(var i = 0; i < el.length; ++i) { 
result = el[i]; 
} 

перезаписывает результат переменной каждый раз. Вот почему вы всегда получаете только один элемент.

Вы можете использовать результат снаружи, хотя и итерации через него. Kinda like

var result = window.qsa(el) 
for(var i = 0; i < result.length; ++i) { 
    var workOn = result[i]; 
    // Do something with workOn 
} 
+0

Если бы это помогло, я бы не прочь проголосовать за мой ответ. ;-) –

+0

У меня было бы миллион раз, но у меня нет 15 очков реплики, но, к сожалению, я еще не могу продвинуться. – Malik

+0

Конечно ... неважно. Продолжайте. :-) –