Nhận phần tử bên trong phần tử theo lớp và ID - JavaScript


136

Được rồi, tôi đã từng học JavaScript, nhưng điều hữu ích nhất tôi đã viết là trình chuyển đổi kiểu CSS. Vì vậy, tôi hơi mới với điều này. Giả sử tôi có mã HTML như thế này:

<div id="foo">
    <div class="bar">
        Hello world!
    </div>
</div>

Làm thế nào tôi thay đổi "Xin chào thế giới!" đến "Tạm biệt thế giới!" ? Tôi biết cách document.getEuityByClass và document.getEuityById hoạt động, nhưng tôi muốn nhận được cụ thể hơn. Xin lỗi nếu điều này đã được hỏi lúc trước.

Câu trả lời:


232

Chà, trước tiên bạn cần chọn các yếu tố có chức năng như thế nào getElementById.

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];

getElementByIdchỉ trả về một nút, nhưng getElementsByClassNametrả về danh sách nút. Vì chỉ có một phần tử có tên lớp đó (theo như tôi có thể nói), nên bạn chỉ có thể lấy phần tử đầu tiên (đó là những gì [0]dành cho đối tác, nó giống như một mảng).

Sau đó, bạn có thể thay đổi html với .textContent.

targetDiv.textContent = "Goodbye world!";

var targetDiv = document.getElementById("foo").getElementsByClassName("bar")[0];
targetDiv.textContent = "Goodbye world!";
<div id="foo">
    <div class="bar">
        Hello world!
    </div>
</div>


1
Lấy cha mẹ bằng ID là không cần thiết trong trường hợp này. document.getElementsByClassNamesẽ làm việc tốt
rvighne

7
@rvighne các yêu cầu chính xác của OP là anh ấy "muốn được cụ thể hơn". Người đặt câu hỏi đang hỏi làm thế nào anh ta có thể cụ thể hơn trong giao dịch cây DOM của mình. Việc sử dụng getEuityByClassName không phải là một điểm gây nhầm lẫn, nhưng tôi có thể thấy ai đó có thể dễ dàng nghĩ rằng tôi đang chỉ ra cả hai khi cần thiết. Họ không phải. Nếu bạn muốn chỉ nhắm mục tiêu các phần tử của một lớp nhất định nằm dưới một nút cụ thể của một ID nhất định trái ngược với các phần tử của cùng một lớp đó dưới một nút khác, thì đây là những gì bạn sẽ sử dụng.
Joseph Marikle

1
Có thể tốt để chỉnh sửa câu trả lời này và thay đổi .innerHtmlthành .textContentvì lợi ích bảo mật của các bộ mã / sao chép.
Codecripblr

14

Bạn có thể làm như thế này:

var list = document.getElementById("foo").getElementsByClassName("bar");
if (list && list.length > 0) {
    list[0].innerHTML = "Goodbye world!";
}

hoặc, nếu bạn muốn làm điều đó với ít kiểm tra lỗi hơn và ngắn gọn hơn, nó có thể được thực hiện trong một dòng như thế này:

document.getElementById("foo").getElementsByClassName("bar")[0].innerHTML = "Goodbye world!";

Giải thích:

  1. Bạn có được các yếu tố với id="foo".
  2. Sau đó, bạn tìm thấy các đối tượng được chứa trong đối tượng đó có class="bar".
  3. Điều đó trả về một nodeList giống như mảng, vì vậy bạn tham chiếu mục đầu tiên trong nodeList đó
  4. Sau đó, bạn có thể đặt innerHTMLmục đó để thay đổi nội dung của nó.

Hãy cẩn thận: một số trình duyệt cũ hơn không hỗ trợ getElementsByClassName(ví dụ: các phiên bản IE cũ hơn). Chức năng đó có thể được đưa vào vị trí nếu thiếu.


Đây là nơi tôi khuyên bạn nên sử dụng thư viện có hỗ trợ bộ chọn CSS3 tích hợp thay vì lo lắng về khả năng tương thích trình duyệt (hãy để người khác làm tất cả công việc). Nếu bạn chỉ muốn một thư viện để làm điều đó, thì Sizzle sẽ hoạt động rất tốt. Trong Sizzle, điều này sẽ được thực hiện như thế này:

Sizzle("#foo .bar")[0].innerHTML = "Goodbye world!";

jQuery có thư viện Sizzle tích hợp và trong jQuery, đây sẽ là:

$("#foo .bar").html("Goodbye world!");

Cảm ơn bạn, tôi đã gặp rắc rối với document.getEuityBy *. jQuery làm cho mọi thứ dễ dàng hơn nhiều.
Tanner Babcock

7

Nếu điều này cần để hoạt động trong IE 7 hoặc thấp hơn, bạn cần nhớ rằng getElementsByClassName không tồn tại trong tất cả các trình duyệt. Vì điều này, bạn có thể tạo getElementsByClassName của riêng bạn hoặc bạn có thể thử điều này.

var fooDiv = document.getElementById("foo");

for (var i = 0, childNode; i <= fooDiv.childNodes.length; i ++) {
    childNode = fooDiv.childNodes[i];
    if (/bar/.test(childNode.className)) {
        childNode.innerHTML = "Goodbye world!";
    }
}

getElementsByClassNamecũng không hoạt động trong IE8, nhưng bạn có thể sử dụng querySelectorAllở vị trí của nó (dù sao cũng khá nhiều).
dùng113716

@ Ӫ _._ Ӫ ... lol ... bạn đúng nhưng bạn chỉ cần chứng minh câu trả lời của tôi nhiều hơn. Bạn không thể dựa vào getElementsByClassName nếu trang của bạn cần hoạt động trên nhiều trình duyệt. jQuery chắc chắn sẽ là một tùy chọn nhưng vì vậy sẽ có đoạn mã trên.
John Hartsock

Vâng, tôi có nghĩa là nhận xét đó hỗ trợ cho câu trả lời của bạn, nhưng sau đó cũng chỉ ra rằng có thể sử dụng qSAtrong shim để bạn vẫn có thể sử dụng mã gốc trong IE8. Mặc dù xem xét kỹ hơn về giải pháp của bạn, bạn đã có một vài điều cần khắc phục.
dùng113716

@ Ӫ _._ Ӫ ... tò mò bạn thấy gì ... vì tôi không thấy nó.
John Hartsock

var i = 0, var child = fooDiv.childNodes[i]không có hiệu lực. i <= fooDiv.childNodeskhông thực sự có ý nghĩa. childNode.className.test("bar")Không có childNodebiến và một chuỗi không có test()phương thức.
dùng113716

4

Hàm đệ quy :

function getElementInsideElement(baseElement, wantedElementID) {
    var elementToReturn;
    for (var i = 0; i < baseElement.childNodes.length; i++) {
        elementToReturn = baseElement.childNodes[i];
        if (elementToReturn.id == wantedElementID) {
            return elementToReturn;
        } else {
            return getElementInsideElement(elementToReturn, wantedElementID);
        }
    }
}

Có một lỗi nhỏ trong mẫu ở trên. Thay vì ngay lập tức trở lại trong đường dẫn khác, bạn phải kiểm tra xem có thứ gì được tìm thấy trước không. Nếu không, các nút con khác sẽ không được lặp qua. Một cái gì đó như thế này: if (ElementToReturn) {return ElementToReturn; }
Jannik

3

Cách dễ nhất để làm như vậy là:

function findChild(idOfElement, idOfChild){
  let element = document.getElementById(idOfElement);
  return element.querySelector('[id=' + idOfChild + ']');
}

hoặc dễ đọc hơn:

findChild = (idOfElement, idOfChild) => {
    let element = document.getElementById(idOfElement);
    return element.querySelector(`[id=${idOfChild}]`);
}

-4

Bạn không nên sử dụng document.getEuityByID vì công việc của nó chỉ dành cho các điều khiển phía máy khách mà id được sửa. Bạn nên sử dụng jquery thay vì như ví dụ dưới đây.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>                                                                                                             
<div id="foo">
   <div class="bar"> 
          Hello world!
     </div>
</div>

dùng cái này :

$("[id^='foo']").find("[class^='bar']")

// do not forget to add script tags as above

nếu bạn muốn xóa bất kỳ chỉnh sửa nào thì chỉ cần thêm "." đằng sau và thực hiện các hoạt động


10
Sử dụng vũ khí nhiệt hạch để giết một con nai sẽ hoạt động, nhưng hơi quá mức. Sử dụng thư viện jQuery nhiều kb để chọn một phần tử khi Javascript cung cấp chức năng đó trong mã cơ sở của nó thì hơi quá mức.
Danejir
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.