Я не знаком с 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>
у меня неправильная логика или я что-то упускаю в своих кодах?
@tacoshy: цель состоит в том, чтобы обрабатывать щелчок по элементу <a> с помощью JavaScript, а не по умолчанию с помощью HTML. почему? потому что я хочу отправить запрос API на сервер, когда пользователь нажимает ссылку. Возможно, я не знаком с javascript, но знаю, что такое <a> в html. но спасибо
@DarkBee можно ли будет работать? Я перечислю свой вариант, спасибо.
Вы не используете привязки, но запускаете вызов API. Для этого вы используете кнопку или тип ввода submit. Якорь следует использовать только в том случае, если вы хотите перенаправить на другой ресурс, например на другой веб-сайт! Вот почему это проблема XY. Если бы вы использовали правильный элемент, вам не нужно было бы искать решение, предотвращающее поведение привязки по умолчанию, которое вам вообще не нужно.
@tacoshy ок тогда
Используйте let
для товара:
Объявляя элемент с помощью let, его область действия ограничивается блоком итерации цикла, что позволяет избежать проблемы его перезаписи.
let item = nav_item[i].querySelector('a').getAttribute('href');
большое спасибо, теперь все заработало. на самом деле я не знаю об этом, возможно, мне нужно прочитать о переменной javascripts. еще раз спасибо
Способ определения функций называется: IIFE (выражение функции с немедленным вызовом). Этот подход создает новую область функции для каждой итерации, фиксируя текущее значение элемента и передавая его обработчику событий. Когда вы его вызываете, он возвращает текущее значение элемента. Это происходит из последней итерации. Добавляя let, вы ограничиваете область действия переменной.
@Bardia: Обратите внимание, что Генеративный ИИ (например, ChatGPT) запрещен , и прочтите Справочный центр: Политика ИИ. Запрещено использовать инструменты искусственного интеллекта для создания или изменения содержания контента, который вы публикуете в Stack Overflow.
@BardiaMazaheri Я не могу, там написано, что у меня должно быть как минимум 15 репутации, чтобы проголосовать.
@DarkBee, спасибо за уведомление. Я программист, и, к сожалению, английский — мой второй язык. Я проверяю свои ответы, чтобы не ошибиться. Но я стараюсь ничего не вставлять из GPT и писать свое.
Я предпочитаю видеть грамматические и орфографические ошибки, чем явные копии (Chat)GPT. Помните, что, используя GPT для создания кода/контента, вы фактически занимаетесь плагиатом.
Это не подход IIFE.
@tacoshy Ах, ты прав (спасибо за поправку). Нуррахман забыл о части IIFE. Просто учтите, что функция, вызываемая addListener, всегда имеет доступ к последнему значению глобальных переменных после их вызова.
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-адреса домашней страницы — это безопасный вариант.
Это не проблема, с которой сталкивается ОП
сейчас это исправлено после ответа Бардии Мазахери. но спасибо за ваш ответ, больше ответов означает больше возможностей попробовать
Нет, это не так - это даже не решает проблему, с которой сталкивается ОП.
Все, что вам нужно сделать, это настроить прослушиватель кликов, проверить, не является ли клик по тегу 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> в документе, не так ли?
Конечно, но вам нужно добавлять прослушиватель кликов не во весь документ, а в document.getElementById('nav-menu')
.
Поскольку вы не хотите фактического поведения привязки и направляете его на другой ресурс, вам не следует использовать привязку.
Поскольку вы сказали, что хотите выполнить вызов 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 дизайне.
Что касается HTML, вам нужно подумать о том, чего вы пытаетесь достичь и какие семантические теги для этого нужны. Если дело доходит до стиля, то это проблема CSS. Но чтобы ответить на вопрос за вас, в вопросе не хватает контекста в виде деталей. Что вы программируете (веб-сайт, приложение, SPA...), как вы хотите перемещаться и куда? Зачем вам нужно делать вызов API...
Я использую Django и шаблоны Django, моя цель — заставить эту навигацию работать без перезагрузки всей страницы. есть ли какая-нибудь статья или документация по этим каналам передачи данных? Пользовательский интерфейс не является большой проблемой, я могу использовать ИИ для создания дизайна. Мне просто нужна эта навигационная ссылка, чтобы отправить запрос на мой сервер, чтобы я мог изменить некоторые части моего HTML. Я хочу перевести пользователя на другую страницу без полной перезагрузки.
Это означает, что вы хотите написать SPA (одностраничное приложение). Тогда якоря действительно, скорее всего, неправильный подход. Вам следует искать не data-link
, а атрибут данных в MDN WebDocs
оу, окей, спасибо за ответ. я узнал много нового сегодня
почему ты используешь
document.getElementById('nav-menu').querySelectorAll('div')
, а неdocument.querySelectorAll('#nav-menu div')
? Не смешивайте jQuery и JavaScript!<a>
nchors предназначены для перенаправления на другую веб-страницу, чтобы не вызывать API. Итак, вы можете объяснить, что вы на самом деле собираетесь делать. Возможна проблема с XY.