Как я могу повысить эффективность таргетинга на мои html-элементы с помощью Javascript

#javascript #html #performance

#javascript #HTML #Производительность

Вопрос:

У меня есть меню со ссылками, и я заставляю их переключать непрозрачность своего hr на 1, когда я нажимаю на каждую ссылку, конечно, возвращая все остальные ссылки (hrs) в меню к исходной непрозрачности 0, которая у них была ранее (классический интерфейс меню).

Проблема в том, что для достижения этого мне пришлось использовать 2 вложенных цикла for с использованием JS. Из того, что я узнал о нотации Big O, это не очень эффективно, особенно из-за того, что с jquery весь этот код выполняется в одной строке. Мой вопрос в том, как я могу повысить эффективность этого кода только с помощью Vanilla JS?

HTML

 <div className="menu">
    <h6>Home<hr/></h6>
    <h6>Movies<hr/></h6>
    <h6>TV Shows<hr/></h6>
    <h6>Documentaries<hr/></h6>
    <h6>Favorites<hr/></h6>
    <h6>Collection<hr/></h6>
</div>
  

JS

 const menulink = document.querySelectorAll('.menu h6')
for(let item of menulink) {
  item.onclick = () => {
    for(let i=0;i<menulink.length;i  ) {
      menulink[i].querySelector('hr').style.opacity = '0'     
    }
    item.querySelector('hr').style.opacity = '1'
  } 
} 
  

Комментарии:

1. Это не так плохо, как вы думаете. При запуске скрипта ссылки будут повторяться один раз. Позже, при нажатии на ссылку, ссылки будут повторяться снова. Таким образом, на каждое действие пользователя (загрузка, щелчок) вы тратите время, пропорциональное количеству ссылок.

2. верно, я так и понял. В моем случае это не так уж плохо. Но есть ли решение для кого-то, кто создает, скажем, онлайн-библиотеку, и каждая ссылка ведет на другую книгу. Это превратилось бы в огромный цикл, который мог бы легко содержать 1000 ссылок. таким образом, эффективность была бы довольно низкой

3. У меня просто была бы переменная для хранения текущего активного элемента ‘hr’. Когда кто-то нажимает на другой пункт меню, установите для этой переменной непрозрачность в 0, а затем установите для нее новое значение «hr»… вы можете получить элемент clicked из события click, и оттуда вы можете запросить ‘hr’

4. пожалуйста, опубликуйте это как ответ с фрагментом кода, потому что я не совсем понимаю, что вы имеете в виду

5. Ни на одном сайте не было бы всех этих 1000 ссылок на одной странице. Они будут динамически загружать различные наборы ссылок по мере навигации пользователя.

Ответ №1:

Я думаю, вы можете добиться этого, сохранив текущий элемент:

 const menulink = document.querySelectorAll('.menu h6');
let current = null;

for(let item of menulink) {
  item.onclick = () => {
    if (current) current.style.opacity = '0'
    current = item.querySelector('hr')
    current.style.opacity = '1'
  } 
}  
 hr {
  opacity: 0;
}  
 <div class="menu">
    <h6>Home<hr/></h6>
    <h6>Movies<hr/></h6>
    <h6>TV Shows<hr/></h6>
    <h6>Documentaries<hr/></h6>
    <h6>Favorites<hr/></h6>
    <h6>Collection<hr/></h6>
</div>  

Ответ №2:

Смотрите!

 const menulink = document.querySelectorAll('.menu h6')
let activeHr;
for(let item of menulink) {
  item.onclick = (event) => {
    if (activeHr) {
        activeHr.style.opacity = '0';
    }
    
    activeHr = event.currentTarget.querySelector('hr');
    activeHr.style.opacity = '1';
  } 
}   
 hr {
opacity: 0;
}  
 <div class="menu">
    <h6>Home<hr/></h6>
    <h6>Movies<hr/></h6>
    <h6>TV Shows<hr/></h6>
    <h6>Documentaries<hr/></h6>
    <h6>Favorites<hr/></h6>
    <h6>Collection<hr/></h6>
</div>  

Ответ №3:

Все приведенные выше ответы направлены на то, чтобы заставить ваш код работать — вместо того, чтобы рассматривать лучший html и CSS — использование hr не требуется — все, что вам нужно, это установить класс active для элемента и использовать CSS для применения к нему нижней границы.

Чтобы заголовки не перескакивали при нажатии — я добавил прозрачную рамку под каждым h6, а затем, когда вы нажимаете, применяется активный класс, а стиль просто окрашивает нижнюю границу.

Вы не должны использовать html-элемент (hr /) для целей оформления — IMO.

Я также не согласен с использованием h6 здесь — они, по-видимому, не являются заголовками…. но я оставил это на случай, если в коде больше, чем вы показываете — например, если это заголовки, идущие вниз по странице, — но обычный список навигации, по-видимому, был бы здесь более уместен.

Спасибо @Barmar’у за скелет кода, который я использовал, и я согласен с его подходом к использованию активного класса. Обратите внимание, что я использую проверку null для удаления существующего активного класса — хотя это можно было бы облегчить, просто установив для первого заголовка значение active с самого начала.

 const menuLinks = document.querySelectorAll('.menu h6')

for (let menuLink of menuLinks) {
  menuLink.onclick = () => {
    document.querySelector('.menu h6.active')?.classList.remove('active');
    menuLink.classList.add('active');
  }
}  
 .menu h6 {
  padding-bottom: 2px;
  border-bottom: solid 1px transparent;
  transition: all 0.2s ease-in-out
}


.menu h6.active {
  border-bottom-color: #000
}

.menu h6:hover {
  border-bottom-color: #000;
  transition: all 0.25s ease-in-out
}  
 <div class="menu">
  <h6>Home</h6>
  <h6>Movies</h6>
  <h6>TV Shows</h6>
  <h6>Documentaries</h6>
  <h6>Favorites</h6>
  <h6>Collection</h6>
</div>  

Комментарии:

1. Я рассмотрел это, но границы плохо переходят при наведении курсора, поэтому я использовал hrs. Приведенные выше ответы сохранили мой код без его изменения, что является хорошей практикой. Но я все равно ценю ваш ответ, чувак

2. @Uriel Привет — спасибо — Я добавил переход при наведении курсора мыши для изменения цвета при наведении курсора — мне кажется, все в порядке — главное, чтобы переход был на входе и выходе. Обычно у меня переход «out» происходит немного быстрее, чем «in»

Ответ №4:

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

Комментарии:

1. Мне нужно, чтобы JS устанавливал значение hr на непрозрачность 1, когда я нажимаю на него! это не просто для наведения курсора

Ответ №5:

Не устанавливайте стиль напрямую, делайте это через стиль класса CSS. Затем вы можете найти элемент, у которого в данный момент есть класс, и удалить его, добавив класс к вновь выбранному элементу.

 const menulink = document.querySelectorAll('.menu h6')
for (let item of menulink) {
  item.onclick = () => {
    let old = document.querySelector('.menu h6 hr.active');
    if (old) {
      old.classList.remove("active");
    }
    item.querySelector('hr').classList.add("active");
  }
}  
 .menu h6 hr.active {
  opacity: 1;
}

.menu h6 hr {
  opacity: 0;
}  
 <div class="menu">
  <h6>Home
    <hr/>
  </h6>
  <h6>Movies
    <hr/>
  </h6>
  <h6>TV Shows
    <hr/>
  </h6>
  <h6>Documentaries
    <hr/>
  </h6>
  <h6>Favorites
    <hr/>
  </h6>
  <h6>Collection
    <hr/>
  </h6>
</div>  

Ответ №6:

Я бы сначала использовал вместо h6s, если бы это была панель навигации и для количества ссылок этот код не был неэффективным! Приветствую, приятель.