Лучший способ выполнить Javascript на якоре

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

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 ответов


Если вы загружаете контент через 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 может просто изучить фрагмент, чтобы увидеть, какие объекты были доступны и подключаться к тем, которые присутствовали.


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

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

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


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

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

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

function ajaxCallback(content){
  // add content to dom
  // search within newly added content for elements that need binding
}

номер 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