Итерация элемента внутри элемента html div

Я не знаком с javascript и столкнулся с этой странной ситуацией. Я использую javascript для перебора элемента div и получения значений href из всех элементов <a> внутри, цель состоит в том, чтобы обрабатывать щелчок по элементу <a> с помощью JavaScript, а не по умолчанию с помощью HTML.

Итерация работает, но все целевые ссылки заменены на последние значения <a>href.

$(document).ready(function() {
  //NavMenu();
  //NavActive();
  NavClick();
  console.info('tes');
});

function NavClick() {
  var nav_item = document.getElementById('nav-menu').querySelectorAll('div')
  for (let i = 0; i < nav_item.length; i++) {
    item = nav_item[i].querySelector('a').getAttribute('href')
    nav_item[i].addEventListener('click', function(e) {
      e.preventDefault();
      $.ajax({
        url: item,
        contentType: 'application/json',
        dataType: 'json',
        success: function(data) {
          $('title').html(data.title)
          window.history.replaceState({}, '', item)
          $('#content').html(data.data)
        }
      });
    });
  }
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class = "row col-12 justify-content-end" id = "nav-menu">
  <div class = "col-auto">
    <a href = "/" class = "px-1">
            Short
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/myurl/' %}" class = "px-1">
            My URL
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/group/" class = "px-1">
            My Collection
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/group/create/" class = "px-1">
            New Collection
        </a>
  </div>
</div>

Я ожидаю, что мой код добавит прослушиватель событий к каждому элементу и получит значение «href», чтобы я мог отправить запрос на сервер с URL-адресом.

например. когда я нажимаю эту ссылку, javascripts отправляет запрос на 127.0.0.1, но я получаю запрос на отправку 127.0.0.1/group/create/.

<div class = "col-auto">
    <a href = "/" class = "px-1">
        Short
    </a>
</div>

у меня неправильная логика или я что-то упускаю в своих кодах?

почему ты используешь document.getElementById('nav-menu').querySelectorAll('div'), а не document.querySelectorAll('#nav-menu div')? Не смешивайте jQuery и JavaScript! <a>nchors предназначены для перенаправления на другую веб-страницу, чтобы не вызывать API. Итак, вы можете объяснить, что вы на самом деле собираетесь делать. Возможна проблема с XY.

tacoshy 07.08.2024 07:20

@tacoshy: цель состоит в том, чтобы обрабатывать щелчок по элементу <a> с помощью JavaScript, а не по умолчанию с помощью HTML. почему? потому что я хочу отправить запрос API на сервер, когда пользователь нажимает ссылку. Возможно, я не знаком с javascript, но знаю, что такое <a> в html. но спасибо

Nurrahman 07.08.2024 07:46

@DarkBee можно ли будет работать? Я перечислю свой вариант, спасибо.

Nurrahman 07.08.2024 07:48

Вы не используете привязки, но запускаете вызов API. Для этого вы используете кнопку или тип ввода submit. Якорь следует использовать только в том случае, если вы хотите перенаправить на другой ресурс, например на другой веб-сайт! Вот почему это проблема XY. Если бы вы использовали правильный элемент, вам не нужно было бы искать решение, предотвращающее поведение привязки по умолчанию, которое вам вообще не нужно.

tacoshy 07.08.2024 08:28

@tacoshy ок тогда

Nurrahman 07.08.2024 08:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
68
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Используйте let для товара:

Объявляя элемент с помощью let, его область действия ограничивается блоком итерации цикла, что позволяет избежать проблемы его перезаписи.

let item = nav_item[i].querySelector('a').getAttribute('href');

большое спасибо, теперь все заработало. на самом деле я не знаю об этом, возможно, мне нужно прочитать о переменной javascripts. еще раз спасибо

Nurrahman 07.08.2024 07:34

Способ определения функций называется: IIFE (выражение функции с немедленным вызовом). Этот подход создает новую область функции для каждой итерации, фиксируя текущее значение элемента и передавая его обработчику событий. Когда вы его вызываете, он возвращает текущее значение элемента. Это происходит из последней итерации. Добавляя let, вы ограничиваете область действия переменной.

Bardia Mazaheri 07.08.2024 07:43

@Bardia: Обратите внимание, что Генеративный ИИ (например, ChatGPT) запрещен , и прочтите Справочный центр: Политика ИИ. Запрещено использовать инструменты искусственного интеллекта для создания или изменения содержания контента, который вы публикуете в Stack Overflow.

DarkBee 07.08.2024 07:46

@BardiaMazaheri Я не могу, там написано, что у меня должно быть как минимум 15 репутации, чтобы проголосовать.

Nurrahman 07.08.2024 07:49

@DarkBee, спасибо за уведомление. Я программист, и, к сожалению, английский — мой второй язык. Я проверяю свои ответы, чтобы не ошибиться. Но я стараюсь ничего не вставлять из GPT и писать свое.

Bardia Mazaheri 07.08.2024 07:55

Я предпочитаю видеть грамматические и орфографические ошибки, чем явные копии (Chat)GPT. Помните, что, используя GPT для создания кода/контента, вы фактически занимаетесь плагиатом.

DarkBee 07.08.2024 07:58

Это не подход IIFE.

tacoshy 07.08.2024 08:31

@tacoshy Ах, ты прав (спасибо за поправку). Нуррахман забыл о части IIFE. Просто учтите, что функция, вызываемая addListener, всегда имеет доступ к последнему значению глобальных переменных после их вызова.

Bardia Mazaheri 07.08.2024 08:42
function NavClick(){
    const homeurl = 'http://127.0.0.1';
    var nav_item = document.getElementById('nav-menu').querySelectorAll('div')
    for (let i=0; i<nav_item.length; i++){
        item = nav_item[i].querySelector('a').getAttribute('href')
        nav_item[i].addEventListener('click', function(e){
            e.preventDefault();
            $.ajax({
                url: homeurl + item,
                contentType: 'application/json',
                dataType: 'json',
                success: function(data){
                    $('title').html(data.title)
                    window.history.replaceState({}, '', item)
                    $('#content').html(data.data)
                }
            });
        });
    }
}

Надеюсь, это вам поможет. Попробуйте определить homeurl как постоянную переменную.

По умолчанию, если вы нажмете ссылку («/») на странице 127.0.0.1/group/create, по умолчанию она перейдет на ссылку 127.0.0.1/group/create. Поэтому всегда использовать константную переменную для URL-адреса домашней страницы — это безопасный вариант.

Это не проблема, с которой сталкивается ОП

DarkBee 07.08.2024 07:35

сейчас это исправлено после ответа Бардии Мазахери. но спасибо за ваш ответ, больше ответов означает больше возможностей попробовать

Nurrahman 07.08.2024 07:41

Нет, это не так - это даже не решает проблему, с которой сталкивается ОП.

DarkBee 07.08.2024 07:42

Все, что вам нужно сделать, это настроить прослушиватель кликов, проверить, не является ли клик по тегу a, и использовать preventDefault(), чтобы переопределить навигацию.

Никакой петли не требуется. JQuery не требуется.

window.addEventListener('load', () => {
  function hijackLink(event) {
    if (event.target.tagName == 'A') {
      console.info(event.target.href);
      event.preventDefault();    
    }
  }

  document.addEventListener('click', hijackLink);
  // EDIT, due to comment
  // document.getElementById('nav-menu').addEventListener('click', hijackLink)
});
<div class = "row col-12 justify-content-end" id = "nav-menu">
  <div class = "col-auto">
    <a href = "/" class = "px-1">
            Short
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/myurl/' %}" class = "px-1">
            My URL
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/group/" class = "px-1">
            My Collection
        </a>
  </div>
  <div class = "col-auto">
    <a href = "/group/create/" class = "px-1">
            New Collection
        </a>
  </div>
</div>

это повлияет на весь элемент <a> в документе, не так ли?

Nurrahman 07.08.2024 08:21

Конечно, но вам нужно добавлять прослушиватель кликов не во весь документ, а в document.getElementById('nav-menu').

Rickard Elimää 07.08.2024 08:50
Ответ принят как подходящий

Поскольку вы не хотите фактического поведения привязки и направляете его на другой ресурс, вам не следует использовать привязку.
Поскольку вы сказали, что хотите выполнить вызов API, вам следует использовать кнопку в качестве семантического «триггерного элемента сценария». Ссылку/URL-адрес, который вы неправильно разместили внутри href, можно разместить в атрибуте data. В примере кода я дал ему имя link (data-link).

Добавьте прослушиватель событий непосредственно к кнопке и сделайте селектор элементов короче и читабельнее, используя document.querySelectorAll('#nav-menu button'). Затем выполните итерацию по списку узлов (то, что querySelectorAll возвращает) и добавьте прослушиватель событий непосредственно к каждому элементу. Вы также можете изучить делегирование событий, если хотите еще больше улучшить свои навыки JS.
Затем вы можете прочитать URL-адрес, используя this.dataset.link

window.addEventListener('DOMContentLoaded', function() {
  const NAV_ITEMS = document.querySelectorAll('#nav-menu button');
  NAV_ITEMS.forEach(item => {
    item.addEventListener('click', function() {
      const LINK = this.dataset.link;
      console.info(LINK);
    })
  })
});
<div class = "row col-12 justify-content-end" id = "nav-menu">
  <div class = "col-auto">
    <button data-link = "/" class = "px-1">Short</button>
  </div>
  <div class = "col-auto">
    <button data-link = "/myurl/' %}" class = "px-1">My URL</button>
  </div>
  <div class = "col-auto">
    <button data-link = "/group/" class = "px-1">My Collection</button>
  </div>
  <div class = "col-auto">
    <button data-link = "/group/create/" class = "px-1">New Collection</button>
  </div>
</div>

Я перечисляю ваш ответ, я уже попробовал ваше предыдущее предложение и сейчас заменяю тег привязки кнопкой (возможно, я буду использовать что-то другое, если это возможно). это хорошая реализация с использованием кнопки для меню навигации? Я не очень хорош в UI/UX дизайне.

Nurrahman 07.08.2024 09:13

Что касается HTML, вам нужно подумать о том, чего вы пытаетесь достичь и какие семантические теги для этого нужны. Если дело доходит до стиля, то это проблема CSS. Но чтобы ответить на вопрос за вас, в вопросе не хватает контекста в виде деталей. Что вы программируете (веб-сайт, приложение, SPA...), как вы хотите перемещаться и куда? Зачем вам нужно делать вызов API...

tacoshy 07.08.2024 09:16

Я использую Django и шаблоны Django, моя цель — заставить эту навигацию работать без перезагрузки всей страницы. есть ли какая-нибудь статья или документация по этим каналам передачи данных? Пользовательский интерфейс не является большой проблемой, я могу использовать ИИ для создания дизайна. Мне просто нужна эта навигационная ссылка, чтобы отправить запрос на мой сервер, чтобы я мог изменить некоторые части моего HTML. Я хочу перевести пользователя на другую страницу без полной перезагрузки.

Nurrahman 07.08.2024 09:36

Это означает, что вы хотите написать SPA (одностраничное приложение). Тогда якоря действительно, скорее всего, неправильный подход. Вам следует искать не data-link, а атрибут данных в MDN WebDocs

tacoshy 07.08.2024 09:43

оу, окей, спасибо за ответ. я узнал много нового сегодня

Nurrahman 07.08.2024 09:57

Другие вопросы по теме