Какой лучший способ заменить ссылки на JS-функции?
Шаблон, который начал проявлять много в одном из веб-приложений, с которыми я работаю, - это ссылки, которые обычно были регулярной ссылкой на теги, теперь нужно всплывающее окно с вопросом: "Вы уверены?" прежде чем ссылка пойдет. (Если пользователь нажимает на отмену, ничего не происходит.)
У нас есть решение, которое работает, но каким-то образом мы являемся магазином веб-приложений без эксперта Javascript, поэтому я остаюсь с этим обходным ощущением, что есть лучший способ выполнить эту работу.
Итак, эксперты JS, какой самый совместимый со стандартами, кросс-браузерный способ сделать это?
(Для записи это уже сайт, который требует JS, поэтому не нужно иметь версию "не-JS", но она должна работать в любых и абсолютно разумно современных браузерах.)
(Кроме того, для бонусных очков было бы неплохо, если бы люди с JS отключились, а ссылки не работали, а не в обход окна подтверждения.)
Ответы
Ответ 1
Ненавязчивый Javascript
Лучшей практикой является добавление методов обработчика событий к ссылкам.
Функция confirm() создает диалоговое окно, которое вы описали, и возвращает true или false в зависимости от выбора пользователя.
Методы обработчика событий в ссылках имеют особое поведение, а именно: они убивают действие ссылки, если они возвращают false.
var link = document.getElementById('confirmToFollow');
link.onclick = function () {
return confirm("Are you sure?");
};
Если вы хотите, чтобы ссылка на требовала javascript, HTML должен быть отредактирован. Удалите href:
<a href="#" id="confirmToFollow"...
Вы можете явно указать назначение ссылки в обработчике событий:
var link = document.getElementById('confirmToFollow');
link.onclick = function () {
if( confirm("Are you sure?") ) {
window.location = "http://www.stackoverflow.com/";
}
return false;
};
Если вы хотите, чтобы один и тот же метод вызывался по нескольким ссылкам, вы можете получить nodeList ссылок, которые хотите, и применить метод к каждому при прохождении через nodeList:
var allLinks = document.getElementsByTagName('a');
for (var i=0; i < allLinks.length; i++) {
allLinks[i].onclick = function () {
return confirm("Are you sure?");
};
}
Здесь есть дополнительные перестановки той же идеи, такие как использование имени класса, чтобы определить, какие ссылки будут прослушивать метод, и передать уникальное местоположение в каждый из них на основе некоторых других критериев. Они шесть из одного, полдюжины другого.
Альтернативные подходы (не поощряемые практики):
Одна обескураженная практика заключается в прикреплении метода с помощью атрибута onclick:
<a href="mypage.html" onclick="...
Еще одна обескураженная практика заключается в установке атрибута href для вызова функции:
<a href="javascript: confirmLink() ...
Обратите внимание, что эти обескураженные методы - это все рабочие решения.
Ответ 2
Вот как мы это делали:
<a href="#" onClick="goThere(); return false;">Go to new page</a>`
function goThere()
{
if( confirm("Are you sure?") )
{
window.location.href="newPage.aspx";
}
}
(EDIT: код переформатирован, чтобы избежать горизонтальной прокрутки)
Ответ 3
<a href="http://..." onclick="return confirm('are you sure?')">text</a>
Ответ 4
Если вы используете jQuery, вы бы сделали:
jQuery(document).ready(
jQuery("a").click(){
//you'd place here your extra logic
document.location.href = this.href;
}
);
Ответ 5
В jquery это что-то вроде:
$("a").click(function() {if(confirm('yadda yadda')) event.stopPropagation();});
Если я понимаю, что сказал jgreep, если вы хотите, чтобы подтверждение отображалось на нескольких ссылках, вы привязывали обработчик кликов только к ссылкам с правильным классом. Вы можете сделать это только для привязок или для любого элемента html, у которого есть класс.
$(".conf").click(function() {if(confirm('yadda yadda')) event.stopPropagation();});
Ответ 6
Версия для привязки к классу (нет необходимости в встроенных атрибутах onclick): связать это внешнее <script> после всех проверяемых элементов управления:
// dangerous - warnings on potentially harmful actions
// usage: add class="dangerous" to <a>, <input> or <button>
// Optionally add custom confirmation message to title attribute
function dangerous_bind() {
var lists= [
document.getElementsByTagName('input'),
document.getElementsByTagName('button'),
document.getElementsByTagName('a')
];
for (var listi= lists.length; listi-->0;) { var els= lists[listi];
for (var eli= els.length; eli-->0;) { var el= els[eli];
if (array_contains(el.className.split(' '), 'dangerous'))
el.onclick= dangerous_click;
}
}
}
function array_contains(a, x) {
for (var i= a.length; i-->0;)
if (a[i]==x) return true;
return false;
}
function dangerous_click() {
return confirm(this.title || 'Are you sure?');
}
dangerous_bind();
Это немного длинная ветвь из-за привязки, работающей над подачей/кнопками. Вообще, хотя имеет смысл иметь "опасные параметры, которые вы хотите подтвердить на кнопках, а не на ссылках. Запросы GET, запущенные по ссылкам, не должны иметь никакого активного эффекта.
Ответ 7
var links = document.getElementsByTagName('A');
for (var i = 0; i < links.length; i++)
{
links[i].onclick = function ()
{
return Confirm("Are you sure?");
}
}
Это относится ко всем ссылкам, однако его немного сложнее заставить ссылки работать без javascript автоматически (на самом деле это невозможно).
Ответ 8
Взгляните на Каков наилучший способ открыть новое окно браузера. Вы можете сделать что-то подобное, но поднимите подтверждение перед открытием нового окна.