Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   на что навешать обработчик события (https://javascript.ru/forum/misc/29942-na-chto-naveshat-obrabotchik-sobytiya.html)

leko 18.07.2012 12:43

на что навешать обработчик события
 
насколько я знаю обычто навешивают на id или cssClass
но вот к примеру сейчас верстальщик хочет удалить некоторые cssClassы из атрибута class но так как в js эти cssClassы используются удалить их как-то затруднительно

на будущее собираюсь навешать обработчик события на атрибут "data-js-selector", чем это плохо, какие есть подводные камни?
поделитесь опытом/мнением как делаете/сделали бы вы

Deff 18.07.2012 12:48

leko,
Походу Вы говорите о jQuery, посколь навешивать на класс в нативном JS - затруднительно

Magneto 18.07.2012 12:54

leko - Вам нужно разобраться что такое выборка елементов, а что такое навешивание событий.

Событие не навешивается на аттрибуты элемента, событие навешивается на сам элемент. В данном случае по аттрибутам Вы находите элемент на странице и после на сам элемент уже навешиваете событие.

В данном случае никаких проблем не будет, кроме того что JQuery будет немного медлене находить элемент на странице.

melky 18.07.2012 13:11

Цитата:

Сообщение от leko
на будущее собираюсь навешать обработчик события на атрибут "data-js-selector", чем это плохо, какие есть подводные камни?

а как Вы думаете? в каждом "акте" поиска будут проверяться все элементы на странице.
var element = document.querySelector(,,,,,); // БАБАХ!! 20мс сожрали
// тут код
// а тут ещё поиск
var elements = document.querySelectorAll(........); // ВСПЫШКА !!! отожрали 50мс, ибо querySelector прекращает поиск после первого найденного, а эта штука идет дальше.


Цитата:

Сообщение от leko
поделитесь опытом/мнением как делаете/сделали бы вы

идеал - запилить ID нужному элементу, и огораживать верстальщика от этого ИД.

Deff 18.07.2012 13:13

Цитата:

Сообщение от Magneto
кроме того что JQuery будет немного медлене находить элемент на странице.

не факт, принципы то одни, и распарсить в нескольких обрамлениях, на js - скорее всего чел не будет, будет парсить всю страницу - , хотя, к примеру там будет два тего данного класса заранее известно лежащих в div #Wrap1 и div #Wrap2 - так что правота под вопросом
При много тегах - может чаша и склонится в Вашу сторону

Deff 18.07.2012 13:20

Цитата:

Сообщение от melky
идеал - запилить ID нужному элементу, и огораживать верстальщика от этого ИД.

Идеал по скорости событие вешать в тег

melky 18.07.2012 18:51

Цитата:

Сообщение от Deff (Сообщение 189686)
Идеал по скорости событие вешать в тег

а ещё лучше - вешать делегировщика (делегатора, обработчика событий для делегирования, короче :)) событий прямо в боди.

хм ... напомните, почему нельзя вешать обработчики через атрибуты? из-за того, что низя получить объект события?

да вроде можно :

<script>
function rand () {
    return 255 * Math.random() | 0;
}

function delegater (e) {
    e = e || event;
    e = e.target || e.srcElement;
    e.style.backgroundColor = "rgb("+ rand() +", " + rand() + ", " + rand() + ")";
}
</script>
<body onclick="delegater(event)">
<div>DIV</div>
<p>P</p>
<a href="#">A</a>
</body>

Потому что устарело? смешно же.

bes 18.07.2012 20:21

Цитата:

Сообщение от melky
напомните, почему нельзя вешать обработчики через атрибуты?

тут скорее не нельзя, а это ссылка

Цитата:

Сообщение от melky
а ещё лучше - вешать делегировщика (делегатора, обработчика событий для делегирования, короче ) событий прямо в боди

Делегирование, конечно, хорошая вещь, но чтобы вешать прямо на body (типа если id или класс у цели такой-то, то делай то-то).
Имеется в виду лучше для производительности или удобства разработки (или может быть и то и другое)?

melky 18.07.2012 20:54

Цитата:

Сообщение от bes
тут скорее не нельзя, а это ссылка

в отдельно взятом проекте можно этим пренебречь. и подписать в комменте, мол, так и надо, чтобы просматривальщики исходного кода страницы не возмущались.
Цитата:

Сообщение от bes
Делегирование, конечно, хорошая вещь, но чтобы вешать прямо на body (типа если id или класс у цели такой-то, то делай то-то).

live у JQ примерно так работает, и никто не возмущается.
Цитата:

Сообщение от bes
Имеется в виду лучше для производительности или удобства разработки (или может быть и то и другое)?

и того, и другого. вместе, не порознь.

leko 19.07.2012 10:32

Цитата:

Сообщение от Magneto
Событие не навешивается на аттрибуты элемента, событие навешивается на сам элемент. В данном случае по аттрибутам Вы находите элемент на странице и после на сам элемент уже навешиваете событие.

да, ты прав
Цитата:

Сообщение от melky
а ещё лучше - вешать делегировщика (делегатора, обработчика событий для делегирования, короче ) событий прямо в боди.

может я туплю, но не понял что имеется в виду
Цитата:

Сообщение от melky
хм ... напомните, почему нельзя вешать обработчики через атрибуты? из-за того, что низя получить объект события?

а если потом надо поменять функцию, это ж сколько работы, да и вероятность где-то пропустить достаточна высокая

Deff 19.07.2012 10:38

leko,
<a onclick="B_Funck()" >Тут что то</a>
Ни наю - что Вы пропустите Изменив функцию - ведь тег не измениться
Проще имхо дописывать в тег ссылку на функцию, нежели атрибут

bes 19.07.2012 10:44

Цитата:

Сообщение от leko
Сообщение от melky
а ещё лучше - вешать делегировщика (делегатора, обработчика событий для делегирования, короче ) событий прямо в боди.
может я туплю, но не понял что имеется в виду

События всплывают, поэтому можно обрабатывать их на родителе, а не на самих элементах

leko 19.07.2012 11:37

Цитата:

Сообщение от Deff
Ни наю - что Вы пропустите Изменив функцию - ведь тег не измениться

<a class="favorites" onclick="B_Funck()" >Тут что то</a> // таких строк в проекте встречается 20, 50, 100 раз
vs
$('.favorites').click(B_Funck)
надо поменять функцию, и что будем делать в первом варианте?
Цитата:

Сообщение от bes
События всплывают, поэтому можно обрабатывать их на родителе, а не на самих элементах

спасибо, теперь понял

bes 19.07.2012 11:43

Цитата:

Сообщение от leko
надо поменять функцию, и что будем делать в первом варианте?

Для таких случаев и вешают обработчик на родителя, если мало, можно и в атрибут

Deff 19.07.2012 11:47

Цитата:

Сообщение от leko
vs
$('.favorites').click(B_Funck)

Функция будет тогда выглядеть не так - а так:
function B_Funck (){
Тут и меняете , что захотите

}

Пример
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>

<a class="favorites" onclick="return B_Funck(this)" >Тут что то(Клик)</a>
<script type="text/javascript">
function B_Funck (a){
  alert($(a).text());
  return false;
}
</script>

Поменяли
<script type="text/javascript" src="http://yandex.st/jquery/1.4.4/jquery.min.js"></script>


<a class="favorites" onclick="return B_Funck(this)" >Тут что то(Клик)</a>
<script type="text/javascript">
function B_Funck (a){
  $(a).css({'color':'red'})
  return false;
}
</script>


Eще поменяли
<a class="favorites" href="" onclick="return B_Funck(this)" >Тут что то(Клик)</a>
<script type="text/javascript">
function B_Funck (a){
  //this.href='http://javascript.ru/forum/misc/29942-na-chto-naveshat-obrabotchik-sobytiya-2.html#post189855';
  window.open('http://javascript.ru/forum/misc/29942-na-chto-naveshat-obrabotchik-sobytiya-2.html#post189855');
  return true;
}
</script>

bes 19.07.2012 12:14

Deff, способ, конечно, хороший, но если элементов много и они не создаются динамически в цикле, чтобы в каждом не писать обработчик (к тому же может захотеться поменять имя у функции), проще сделать делегированием.
Тут думаю палка о двух концах: с одной стороны легче понять, что будет делать элемент, если у него обработчик в атрибуте (если он в виде функции, придётся найти и её), с другой стороны, удобнее смотреть обработчик для группы элементов (но придётся найти, где он задан), а не на каждый элемент по отдельности.

Deff 19.07.2012 12:16

bes,
Вопрос номер 1:
Это, - где ТС собрался прописывать атрибуты - если на серве (Судя по предыдущим замечаниям) то прописать атрибут или обработчик в теге - однофигственно, но последующих забот - с функцией меньше

bes 19.07.2012 12:39

Цитата:

Сообщение от Deff
bes,
Вопрос номер 1:
Это где он собрался прописывать атрибуты - если на серве (Судя по предыдущим замечаниям) то прописать атрибут или обработчик в теге - однофигственно, но последующих забот - с функцией меньше

Я к тому, что используя делегирование их можно вообще не писать.
PS: начинает доходить вся польза от обработчиков на body: смотришь на элемент (его класс или id), смотришь на обработчики на body, находишь этот элемент в обработчиках, понимаешь, что он делает.

Deff 19.07.2012 13:14

Цитата:

Сообщение от bes
Я к тому, что используя делегирование их можно вообще не писать.

С одной стороны полностью согласен, с другой - часто удобно смотря на элемент в исходнике страницы понимать чем он обрабатывается (Хотя бы по классу

bes 19.07.2012 13:20

Цитата:

Сообщение от Deff
С одной стороны полностью согласен, с другой - часто удобно смотря на элемент в исходнике страницы понимать чем он обрабатывается (Хотя бы по классу

При обработке на body как раз класс или id нужен, только искать уже теперь придётся не по всему коду, а только в обработчиках body

bes 19.07.2012 14:11

Вроде очень даже удобная схема получается
<input type="button" value="click" class="but1">
<input type="button" value="click" class="but2">

<script>
window.onload = function () {//onload begin

  document.body.onclick = function (e) {//onclick begin
    e = e || event;
    var target = e.target || e.srcElement;
    
    if (target.className == 'but1') {
      alert(target.className);
      return;
    }

    if (target.className == 'but2') {
      alert(target.className);
      return;
    }

  }//onclick end

}//onload end
</script>


<input type="button" value="click" class="but1">
<input type="button" value="click" class="but2">

<script>
window.onload = function () {//onload begin

  document.body.onclick = function (e) {//onclick begin
    e = e || event;
    var target = e.target || e.srcElement;
    
    if (target.className == 'but1') {
      alert(target.className);
    } else 

    if (target.className == 'but2') {
      alert(target.className);
    }

  }//onclick end

}//onload end
</script>


<input type="button" value="click" class="but1">
<input type="button" value="click" class="but2">

<script>
window.onload = function () {//onload begin

  document.body.onclick = function (e) {//onclick begin
    e = e || event;
    var target = e.target || e.srcElement;
    
    switch (target.className) {//switch begin
      case 'but1': {
        alert(target.className);
        break;
      }
      case 'but2': {
        alert(target.className);
        break;
      }
    }//switch end

  }//onclick end

}//onload end
</script>

melky 19.07.2012 15:25

Цитата:

Сообщение от leko
а если потом надо поменять функцию, это ж сколько работы, да и вероятность где-то пропустить достаточна высокая

что там можно упустить, если абсолютно все обработчики весят на body?

Цитата:

Сообщение от leko
таких строк в проекте встречается 20, 50, 100 раз

да хоть 9000, всё равно обработчик то один. а приведённый пример JQ, кстати, будет обходить все эти элементы :)

Цитата:

Сообщение от Deff
с другой - часто удобно смотря на элемент в исходнике страницы понимать чем он обрабатывается (Хотя бы по классу

а ещё легче понять, когда перед тобой (глазами, т.е.) висит хеш, где ключ - селектор, а функция - значение. так ещё проще понять, что, куда и зачем.

Цитата:

Сообщение от bes
При обработке на body как раз класс или id нужен, только искать уже теперь придётся не по всему коду, а только в обработчиках body

JQ засирает элементы, давая им всем ID (или другой атрибут), коим является рандомное число. это число используется для $.data, и, как Вы уже поняли, для лёгкого делегирования. Вывод сделайте сами :)

Цитата:

Сообщение от bes
Вроде очень даже удобная схема получается

можно сделать проще - как я имел в виду.

Цитата:

Сообщение от melky (Сообщение 189747)
<script>
function rand () {
    return 255 * Math.random() | 0;
}

function delegater (e) {
    e = e || event;
    e = e.target || e.srcElement;
    e.style.backgroundColor = "rgb("+ rand() +", " + rand() + ", " + rand() + ")";
}
</script>

<body *!*onclick="delegater(event)"*/!*>
    <div>DIV</div>
    <p>P</p>
    <a href="#">A</a>
</body>

потестировал в IE10 в режиме эмуляции IE7, и во всех свежаках. работает :)

единственная проблема возникнет, когда захочется проделегировать НЕвсплывающие события - к хорошему быстро привыкаешь

bes 19.07.2012 15:34

Цитата:

Сообщение от melky
можно сделать проще - как я имел в виду.

Ну почти тоже самое.
Только если для каждого элемента задавать разные обработчики, то всё равно их придётся как-то распознавать (например, по классу или id)


Часовой пояс GMT +3, время: 12:35.