Phương thức querySelectorAll và getElementsBy * trả về gì?

May 22 2012

Đỗ getElementsByClassName(và chức năng tương tự như getElementsByTagNamequerySelectorAll) làm việc giống như getElementByIdhay họ trả về một mảng của các nguyên tố?

Lý do tôi hỏi là vì tôi đang cố gắng thay đổi kiểu của tất cả các phần tử đang sử dụng getElementsByClassName. Xem bên dưới.

//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';

//works
document.getElementById('myIdElement').style.size = '100px';

Trả lời

155 ThiefMaster May 22 2012 at 06:18

getElementById()Mã của bạn hoạt động vì ID phải là duy nhất và do đó hàm luôn trả về chính xác một phần tử (hoặc nullnếu không tìm thấy phần tử nào).

Tuy nhiên, getElementsByClassName(), querySelectorAll(), và các getElementsBy*phương pháp trả về một bộ sưu tập mảng giống như các yếu tố. Lặp lại nó giống như bạn làm với một mảng thực:

var elems = document.getElementsByClassName('myElement');
for(var i = 0; i < elems.length; i++) {
    elems[i].style.size = '100px';
}

Nếu bạn thích thứ gì đó ngắn hơn, hãy cân nhắc sử dụng jQuery :

$('.myElement').css('size', '100px');
20 AlvaroJoao Feb 15 2016 at 09:53

Bạn đang sử dụng một mảng làm đối tượng, sự khác biệt giữa getElementbyIdgetElementsByClassNamelà:

getElementsByClassName

Các getElementsByClassName(classNames)phương pháp có một chuỗi chứa hổn độn của các thẻ không gian tách biệt độc đáo đại diện cho các lớp học. Khi được gọi, phương thức phải trả về một NodeListđối tượng trực tiếp chứa tất cả các phần tử trong tài liệu có tất cả các lớp được chỉ định trong đối số đó, lấy được các lớp bằng cách tách một chuỗi trên khoảng trắng. Nếu không có mã thông báo nào được chỉ định trong đối số, thì phương thức phải trả về một NodeList trống.

https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname

getElementById

Phương thức getElementById () truy cập phần tử đầu tiên với id đã chỉ định.

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

trong mã của bạn các dòng:

1- document.getElementsByClassName ('myElement'). Style.size = '100px';

sẽ KHÔNG hoạt động như mong đợi, vì getElementByClassNamesẽ trả về một mảng và mảng sẽ KHÔNG có thuộc styletính, bạn có thể truy cập từng thuộc tính elementbằng cách lặp qua chúng.

Đó là lý do tại sao hàm getElementByIdlàm việc cho bạn, hàm này sẽ trả về đối tượng trực tiếp. Do đó bạn sẽ có thể truy cập styletài sản.

11 remdevtec Jan 07 2016 at 16:14

Mô tả sau được lấy từ trang này :

Phương thức getElementsByClassName () trả về một tập hợp tất cả các phần tử trong tài liệu với tên lớp được chỉ định, dưới dạng một đối tượng NodeList.

Đối tượng NodeList đại diện cho một tập hợp các nút. Các nút có thể được truy cập bằng số chỉ mục. Chỉ số bắt đầu từ 0.

Mẹo: Bạn có thể sử dụng thuộc tính độ dài của đối tượng NodeList để xác định số lượng phần tử có tên lớp được chỉ định, sau đó bạn có thể lặp qua tất cả các phần tử và trích xuất thông tin bạn muốn.

Vì vậy, như một tham số getElementsByClassNamesẽ chấp nhận một tên lớp.

Nếu đây là nội dung HTML của bạn:

<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>

sau đó var menuItems = document.getElementsByClassName('menuItem')sẽ trả về một tập hợp (không phải mảng) gồm 3 chữ cái trên <div>, vì chúng khớp với tên lớp đã cho.

Sau đó, bạn có thể lặp lại tập hợp các nút này ( <div>trong trường hợp này) với:

for (var menuItemIndex = 0 ; menuItems.length ; menuItemIndex ++) {
   var currentMenuItem = menuItems[menuItemIndex];
   // do stuff with currentMenuItem as a node.
}

Vui lòng tham khảo bài đăng này để biết thêm về sự khác biệt giữa các phần tử và các nút.

11 kinduser Feb 22 2017 at 06:07

ES6 cung cấp Array.from()phương thức, phương thức này tạo ra một thể hiện Mảng mới từ một đối tượng giống mảng hoặc có thể lặp lại.

let boxes = document.getElementsByClassName('box');

Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

Như bạn có thể thấy bên trong đoạn mã, sau khi sử dụng Array.from()hàm, bạn có thể thao tác trên từng phần tử.


Cùng một giải pháp sử dụng jQuery.

$('.box').css({'background':'green'});
.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

7 Thielicious Oct 23 2017 at 18:41

Nói cách khác

  • document.querySelector()chỉ chọn một phần tử đầu tiên của bộ chọn được chỉ định. Vì vậy, nó không tạo ra một mảng, nó là một giá trị duy nhất. Tương tự như document.getElementById()chỉ tìm nạp phần tử ID, vì ID phải là duy nhất.

  • document.querySelectorAll()chọn tất cả các phần tử với bộ chọn được chỉ định và trả về chúng trong một mảng. Tương tự như chỉ document.getElementsByClassName()dành cho các lớp và document.getElementsByTagName()thẻ.


Tại sao sử dụng querySelector?

Nó chỉ được sử dụng với mục đích duy nhất là dễ dàng và ngắn gọn.


Tại sao sử dụng getElement / sBy? *

Hiệu suất nhanh hơn.


Tại sao sự khác biệt về hiệu suất này?

Cả hai cách lựa chọn đều có mục đích tạo NodeList để sử dụng thêm. querySelectors tạo ra một NodeList tĩnh với các bộ chọn do đó nó phải được tạo từ đầu.
getElement / sBy * ngay lập tức điều chỉnh NodeList hiện có của DOM hiện tại.

Vì vậy, khi nào sử dụng phương pháp nào là tùy thuộc vào bạn / dự án của bạn / thiết bị của bạn.


Infos

Demo tất cả các phương pháp Kiểm tra hiệu suất
tài liệu NodeList

4 atilkan Jun 17 2016 at 10:21

Nó trả về danh sách giống như mảng.

Bạn làm cho nó một Mảng làm ví dụ

var el = getElementsByClassName("elem");
el = Array.prototype.slice.call(el); //this line
el[0].appendChild(otherElem);  
4 Sergey Jul 03 2017 at 02:29

Bạn có thể nhận được một phần tử duy nhất bằng cách chạy

document.querySelector('.myElement').style.size = '100px';

nhưng nó sẽ hoạt động cho phần tử đầu tiên với lớp .myElement.

Nếu bạn muốn áp dụng điều này cho tất cả các phần tử với lớp, tôi khuyên bạn nên sử dụng

document.querySelectorAll('.myElement').forEach(function(element) {
    element.style.size = '100px';
});
4 IrinaMityugova Nov 25 2018 at 11:06
/*
 * To hide all elements with the same class, 
 * use looping to reach each element with that class. 
 * In this case, looping is done recursively
 */

const hideAll = (className, i=0) => {
if(!document.getElementsByClassName(className)[i]){ //exits the loop when element of that id does not exist
  return; 
}

document.getElementsByClassName(className)[i].style.visibility = 'hidden'; //hide element
return hideAll(className, i+1) //loop for the next element
}

hideAll('appBanner') //the function call requires the class name
MatasVaitkevicius Apr 20 2015 at 23:03

Với ES5 + (bất kỳ được duyệt hiện nay - 2017), bạn sẽ có thể làm

[].forEach.call(document.getElementsByClassName('answer'), function(el) {
    el.style.color= 'red';
});

Cat Jul 11 2020 at 08:18

Một câu trả lời cho trường hợp cụ thể của Drenzii ...

Bạn có thể tạo một hàm hoạt động cho bất kỳ wordphần tử nào và chuyển vào số của phần tử bạn muốn chuyển đổi, như:

// Binds `wordButtons` to an (array-like) HTMLCollection of buttons
const wordButtons = document.getElementsByClassName("word");

// Applies the `slantWord` function to the first word button
slantWord(1);

// Defines the `slantWord` function
function slantWord(wordNumber) {
  const index = wordNumber - 1; // Collection index is zero-based
  wordButtons[index].style.transform = "rotate(7deg)"; // Transforms the specified button
}
<div class="wordGameContainer">
  <button class="word word1">WORD 1</button>
  <button class="word word2">WORD 2</button>
  <button class="word word3">WORD 3</button>
  <button class="word word4">WORD 4</button>
</div>

<div>
  <button onclick="moveWord()" class="playButton">PLAY</button>
</div>