Лучший способ выполнить Javascript на якоре - PullRequest
12 голосов
/ 22 сентября 2011

Как правило, есть 3 способа (о которых я знаю), чтобы выполнить javascript из тега <a/>:

1) Использование onclick():

<a href="#" onclick="alert('hello'); return false">hello</a>

2) Прямая ссылка:

<a href="javascript:alert('hello')">hello</a>

3) Или прикрепить внешне:

// In an onload event or similar
document.getElementById('hello').onclick = window.alert('Hello'); 
return false;
<a id="hello" href="#">hello</a>

Я на самом деле загружаю ссылку через AJAX, так что # 3 в основном отсутствует. Так что, лучше сделать №1 или №2 или что-то совершенно другое? Кроме того, почему? О каких подводных камнях я должен знать?

Также отметим, что якорь действительно нигде не связывается, поэтому href="#", я использую a, поэтому стили соответствуют, так как это все еще объект, по которому нужно щелкнуть, а кнопка не подходит в контексте.

Спасибо

Ответы [ 4 ]

3 голосов
/ 22 сентября 2011

Если вы загружаете контент через ajax и вам нужно подключить обработчики событий, у вас есть следующие варианты:

  1. Поместите обработчик JavaScript в ваш HTML с вашим вариантом 1) или 2). На мой взгляд, вариант 1) является более чистым способом его определения, но я не думаю, что есть разница между 1) или 2) - они оба по сути делают одно и то же. Я вообще не фанат этой опции, потому что думаю, что есть смысл хранить разметку и код отдельно.
  2. После загрузки контента с помощью ajax, вызовите некоторый локальный код, который найдет и подключит все ссылки. Это был бы тот же самый код, который вы использовали бы на своей странице и выполняли бы в DOMReady, если бы HTML был статическим HTML на вашей странице. Я бы использовал addEventListener (отступая к attachEvent), чтобы подключить этот путь, так как он более аккуратно допускает несколько слушателей для одного объекта.
  3. Вызовите некоторый код после загрузки контента с помощью ajax, который найдет все ссылки и подключит клики к некоторому универсальному обработчику кликов, который затем может просмотреть метаданные в ссылке и выяснить, что следует делать с этим кликом, на основе метаданные. Например, эти метаданные могут быть атрибутами по нажатой ссылке.
  4. Когда вы загружаете контент, также загружаете код, который может найти каждую ссылку по отдельности, и подключите соответствующий обработчик событий для каждой ссылки так же, как если бы контент просто загружался на обычной странице. Это позволит удовлетворить желание отделить HTML от JS, поскольку JS найдет каждую подходящую ссылку и подключит для нее обработчик события с помощью addEventListener или attachEvent.
  5. Так же, как работает jQuery .live(), подключите общий обработчик событий для необработанных кликов по ссылкам на уровне документа и отправляйте каждый клик на основе метаданных в ссылке.
  6. Запустите некоторый код, который использует реальный фреймворк, такой как jQuery .live(), вместо создания вашей собственной возможности.

То, что я буду использовать, будет немного зависеть от обстоятельств.

Прежде всего, из трех ваших вариантов присоединения обработчика событий я бы использовал новую опцию # 4. Я бы использовал addEventListener (отступая к attachEvent для старых версий IE), а не присваивая onclick, потому что это более чисто учитывает несколько слушателей на элементе. Если бы это был я, я бы использовал каркас (jQuery или YUI), который делает кросс-браузерную совместимость невидимой. Это позволяет полностью разделить HTML и JS (без JS, встроенного в HTML), что, на мой взгляд, желательно в любом проекте с участием более чем одного человека и кажется мне чище ..

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

Если бы было много разных фрагментов HTML, которые я загружал динамически, и было бы чище, если бы все они были "автономными" и поддерживались отдельно, тогда я бы хотел загрузить и HTML, и соответствующий код одновременно, поэтому иметь дескриптор недавно загруженного кода, подключенный к соответствующим ссылкам.

Если бы общая автономная система на самом деле не требовалась, потому что нужно было загрузить только несколько фрагментов, и код для их обработки мог бы быть предварительно включен на странице, тогда я, вероятно, просто сделал бы вызов функции после HTML-фрагмент был загружен через ajax, чтобы подключить javascript к ссылкам в только что загруженном фрагменте. Это сохранит полное разделение между HTML и JS, но будет довольно легко реализовать. Вы можете поместить в каждый фрагмент некоторый ключевой объект, который бы идентифицировал, какой фрагмент JS вызывать, или мог бы использоваться в качестве параметра для передачи в JS, или JS мог бы просто изучить фрагмент, чтобы увидеть, какие объекты были доступны, и подключить к нему. какие бы ни присутствовали.

1 голос
/ 05 июня 2015

Современные браузеры поддерживают Политика безопасности контента или CSP. Это наивысший уровень веб-безопасности и настоятельно рекомендуется, если вы можете применить его, потому что он полностью блокирует все XSS-атаки .

Способ, которым CSP делает это, отключает все векторы, где пользователь может внедрить Javascript на страницу - в вашем вопросе это варианты 1 и 2 (особенно 1).

По этой причине оптимальным вариантом всегда является вариант 3, так как любой другой параметр будет недоступен, если включен CSP.

0 голосов
/ 22 сентября 2011

Номер 3 не "вне", если вы хотите загрузить через AJAX.

var link = document.createElement("a");
//Add attributes (href, text, etc...)
link.onclick = function () { //This has to be a function, not a string
    //Handle the click
    return false; //to prevent following the link
};
parent.appendChild(link); //Add it to the DOM
0 голосов
/ 22 сентября 2011

Я твердо верю в разделение JavaScript и разметки. ИМХО, должно быть четкое различие между тем, что предназначено для отображения, и тем, что предназначено для выполнения. При этом избегайте использования атрибута onclick и встраивания javascript:* в атрибут href.

Альтернативы

  1. Вы можете включать файлы библиотеки javascript, используя AJAX.
  2. Вы можете настроить javascript для поиска изменений в DOM (т. Е. Если это «стандартная задача», заставьте якорь использовать имя класса CSS, которое можно использовать для привязки определенного механизма при последующем динамическом добавлении. (JQuery делает отличная работа с .delegate()))
  3. Запустите ваши сценарии POST-AJAX вызова. (Введите новый контент, затем используйте javascript, чтобы [пере] связать функциональность), например ::

function ajaxCallback(content){
  // add content to dom
  // search within newly added content for elements that need binding
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...