Отримати елемент всередині елемента за класом та ID - JavaScript


136

Добре, я вже давно займався JavaScript, але найкорисніше, що я написав, - це перемикач стилів CSS. Тож я дещо новачок у цьому. Скажімо, у мене є такий HTML-код:

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

Як би я змінив "Привіт, світ!" до "Прощай світ!" ? Я знаю, як працюють document.getElementByClass і document.getElementById, але я хотів би отримати більш конкретну інформацію. Вибачте, якщо про це запитували раніше.

Відповіді:


233

Ну, спочатку потрібно вибрати елементи з такою функцією getElementById.

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

getElementByIdповертає лише один вузол, але getElementsByClassNameповертає список вузлів. Оскільки є лише один елемент із назвою цього класу (наскільки я можу сказати), ви можете просто отримати перший (саме для чого це [0]- це просто як масив).

Потім ви можете змінити html за допомогою .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
Отримати батьків за ідентифікатором в цьому випадку не потрібно. document.getElementsByClassNameспрацювало б добре.
rvighne

7
@rvighne точні вимоги ОП полягали в тому, що він "хотів би отримати більш конкретні". Людина, яка задає питання, запитувала, як він може бути більш конкретним у своєму обході дерева DOM. Використання getElementByClassName не викликало плутанини, але я можу бачити, як хтось може легко подумати, що я вказував як на необхідність. Вони не. Якщо ви хочете націлити лише елементи певного класу, які знаходяться під певним вузлом даного ідентифікатора, на відміну від елементів цього ж класу під іншим вузлом, це саме те, що ви використовуєте.
Джозеф Марікле

1
Можливо, добре відредагувати цю відповідь та змінити .innerHtmlна .textContentкористь для безпеки копіювальних / вставних кодерів.
codecribblr

14

Ви можете це зробити так:

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

або, якщо ви хочете зробити це за допомогою меншої перевірки помилок та більшої стислості, це можна зробити в одному рядку, як це:

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

У поясненні:

  1. Ви отримуєте елемент за допомогою id="foo".
  2. Потім ви знайдете об'єкти, що містяться в цьому об'єкті, які є class="bar".
  3. Це повертає nodeList, схожий на масив, тому ви посилаєтесь на перший елемент у цьому nodeList
  4. Потім ви можете встановити innerHTMLцей елемент, щоб змінити його вміст.

Застереження: деякі старі браузери не підтримують getElementsByClassName(наприклад, старіші версії IE). Ця функція може бути заміщена, якщо її немає.


Тут я рекомендую використовувати бібліотеку, яка має вбудовану підтримку селектора CSS3, а не турбуватися про сумісність браузера самостійно (нехай хтось інший виконує всю роботу). Якщо ви хочете, щоб це робила лише бібліотека, то Sizzle чудово працюватиме. У Sizzle це буде зроблено так:

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

jQuery має вбудовану бібліотеку Sizzle, а в jQuery це:

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

Дякую, у мене виникли проблеми з document.getElementBy *. jQuery значно спрощує справи.
Таннер Бабкок

7

Якщо це потрібно працювати в IE 7 або нижчій, вам потрібно пам’ятати, що getElementsByClassName існує не у всіх браузерах. Через це ви можете створити власний getElementsByClassName або спробувати це.

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!";
    }
}

getElementsByClassNameНе працює і в IE8, але ви можете використовувати querySelectorAllйого місце (майже все одно).
користувач113716

@ Ӫ _._ Ӫ ... lol ... твоя правильна, але ти ще більше підтвердиш мою відповідь. Ви не можете покластися на getElementsByClassName, якщо вашій сторінці потрібно функціонувати в декількох браузерах. jQuery, безумовно, буде варіантом, але так, як зазначено вище.
Джон Харцок

Так, я мав на увазі цей коментар на підтримку вашої відповіді, але потім також зазначив, що це можливо використовувати qSAв shim, щоб ви все ще могли використовувати нативний код в IE8. Незважаючи на детальне вивчення вашого рішення, у вас є кілька речей, які потребують виправлення.
користувач113716

@ Ӫ _._ Ӫ ... цікаво, що ти бачиш ... бо я цього не бачу.
Джон Хартсок

var i = 0, var child = fooDiv.childNodes[i]недійсний. i <= fooDiv.childNodesнасправді не має сенсу. childNode.className.test("bar")Немає childNodeзмінної, і рядок не має test()методу.
користувач113716

4

Рекурсивна функція:

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);
        }
    }
}

У зразку вище є незначна помилка. Замість того, щоб миттєво повернутися в інший шлях, ви повинні перевірити, чи щось було знайдено спочатку. Інакше інші дочірні вузли не будуть пропущені. Приблизно так: if (elementToReturn) {return elementToReturn; }
Jannik

3

Найпростіший спосіб зробити це:

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

або краще для читання:

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

-4

Ви не повинні використовувати document.getElementByID, оскільки його робота лише для керування стороною клієнта, які ідентифіковані. Натомість слід використовувати jquery, як, наприклад, нижче.

<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>

використовуй це :

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

// do not forget to add script tags as above

якщо ви хочете видалити будь-яку операцію, редагуйте будь-яку операцію, тоді просто додайте "". позаду і робити операції


10
Використання термоядерної зброї для вбивства оленя буде спрацьовувати, але це незначне перенапруження. Використання бібліотеки jQuery з декількома кб для вибору елемента, коли Javascript пропонує, щоб функціональність у його базовому коді була дещо більше.
Danejir
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.