Поиск класса html посредством javascript

Есть html разметка:

<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>

Задача:

Если есть в разметке div с классом sidebar, нужно div с классом content добавить еще один класс right.

Прошу помощи в реализации.


Ответы (4 шт):

Автор решения: Pr0gramm1st

Попробуйте такой подход:

let wrapper = document.querySelector('.wrapper'); //Здесь мы находим "главного" нужной нам разметки наших `.sidebar` и `.content`.

if (wrapper.querySelector('.sidebar') { // чтобы уже здесь искать класс `.sidebar` только в нужном родителе
   wrapper.querySelector('.content').classList.add('right'); //и, если найдём, добавить класс `.right` к элементу `.content`
}
→ Ссылка
Автор решения: ΝNL993

Умещаю всё в одну строку:

document.querySelector('div.sidebar') ? document.querySelector('div.content').classList.add('right') : null
<div class="wrapper">
    <div class="sidebar">1</div>
    <div class="content">2</div>
</div>

А если делать красивый код тогда вот:

document.querySelector('div.sidebar')
  ? document.querySelector('div.content').classList.add('right')
  : null
<div class="wrapper">
    <div class="sidebar">1</div>
    <div class="content">2</div>
</div>

→ Ссылка
Автор решения: EzioMercer

На самом деле тут несколько способов решить задачу, в зависимоти от того что именно нужно:

  • Если во всей разметке может быть только 1 div.sidebar и 1 div.content и они могут быть расположены где угодно (т.е. не факт что они будут соседями), то можно сделать так:

document.querySelector('div.sidebar') ? document.querySelector('div.content').classList.add('right') : null;

// Ну или более сокращённо, то можно так

document.querySelector('div.sidebar') && document.querySelector('div.content').classList.add('right');
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>

  • Если во всей разметке может быть хотябы 1 div.sidebar и сколь угодно много div.content и они могут быть расположены где угодно, то можно сделать так:

const isSidebarExists = document.querySelector('div.sidebar') !== null;

if (isSidebarExists) {
  document.querySelectorAll('div.content').forEach(content => content.classList.add('right'));
}
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>
<div class="content"></div>

  • Если во всей разметке может быть только 1 div.sidebar и 1 div.content и они обязательно соседи, то можно сделать так:

// Если content будет находится непосредственно после sidebar

document.querySelector('div.sidebar + div.content')?.classList.add('right');

// Если у content и sidebar просто общий предок, но content всё равно идёт после sidebar

document.querySelector('div.sidebar ~ div.content')?.classList.add('right');

// Если у content и sidebar просто общий предок

document.querySelector('div.sidebar').parentNode.querySelector(':scope > div.content')?.classList.add('right')
<div class="wrapper">
    <div class="content"></div>
    <div class="sidebar"></div>
    <div class="content"></div>
</div>

  • Если во всей разметке может быть сколь угодно много div.sidebar и для каждого из них может быть существует 1 соседний div.content, то можно сделать так:

// Если content находится непосредственно после sidebar

document.querySelectorAll('div.sidebar').forEach(sidebar => {
  sidebar.parentNode.querySelector('div.sidebar + div.content')?.classList.add('right');
})


// Если у content и sidebar просто общий предок, но content всё равно идёт после sidebar

document.querySelectorAll('div.sidebar').forEach(sidebar => {
  sidebar.parentNode.querySelector('div.sidebar ~ div.content')?.classList.add('right');
})


// Если у content и sidebar просто общий предок

document.querySelectorAll('div.sidebar').forEach(sidebar => {
  sidebar.parentNode.querySelector(':scope > div.content')?.classList.add('right');
})
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>
<div class="wrapper">
    <div class="sidebar"></div>
</div>
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>

  • Если во всей разметке может быть сколь угодно много div.sidebar и для каждого из них может быть существует сколь угодно много соседних div.content, то можно сделать так:

// Если у content и sidebar просто общий предок, но content всё равно идёт после sidebar

document.querySelectorAll('div.sidebar').forEach(sidebar => {
  sidebar.parentNode.querySelectorAll('div.sidebar ~ div.content').forEach(content => {
    content.classList.add('right');
  });
})


// Если у content и sidebar просто общий предок

document.querySelectorAll('div.sidebar').forEach(sidebar => {
  sidebar.parentNode.querySelectorAll(':scope > div.content').forEach(content => {
    content.classList.add('right');
  });
})
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
</div>
<div class="wrapper">
    <div class="sidebar"></div>
</div>
<div class="wrapper">
    <div class="sidebar"></div>
    <div class="content"></div>
    <div class="content"></div>
</div>

Но будьте осторожны на счёт :scope его не поддерживает IE

→ Ссылка
Автор решения: novvember

В условии было именно про добавить класс right, но вообще такие задачи на условное форматирование блока часто могут быть решены через селекторы, без javascript. Посмотрите, может, в вашем случае такое тоже применимо.

div {
  outline: 1px solid tomato;
  min-width: 50px;
  min-height: 50px;
  background-color: #eee;
  margin: 10px;
  padding: 5px;
}

.sidebar + .content {
  background-color: tomato;
}
<div class="wrapper">wrapper without sidebar
    <div class="content">content</div>
</div>

<div class="wrapper">wrapper WITH sidebar
    <div class="sidebar">sidebar</div>
    <div class="content">content</div>
</div>

→ Ссылка