Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Контекст this для событий (https://javascript.ru/forum/events/50869-kontekst-dlya-sobytijj.html)

Boolean_Type 15.10.2014 02:03

Контекст this для событий
 
Привет всем! Давненько влотную не работал с JS, посему забыл мелочи. Необходимо вспомнить следующее:
<li id='l' onclick='f(event);'>11111111</li>
<script type="text/javascript">
function f(e){
    alert(e.target); //всё нормально, здесь li
    alert(this); //почему в контексте this - Window? Ф-ция же срабатывает лишь при наведении на li, => и this должен указывать на этот эл-т...
}

document.getElementById('l').onmouseover = function (e) {
	console.log(this) //вот здесь всё нормально, передаётся li. Но ведь в обоих случаях ф-ция является обработчиком СОБЫТИЯ на КОНКРЕТНОМ элементе, в чём же тут дело?
}
</script>

ksa 15.10.2014 08:09

Цитата:

Сообщение от Boolean_Type
Но ведь в обоих случаях ф-ция является обработчиком СОБЫТИЯ на КОНКРЕТНОМ элементе, в чём же тут дело?

В разнице атрибутов и свойств...

danik.js 15.10.2014 08:38

Цитата:

Сообщение от ksa
В разнице атрибутов и свойств...

Неправда.

Boolean_Type, ты неправильно сравнение делаешь.

<button onclick='alert(this);'>this в атрибуте (кликни)</button>
<button id="button2">this в свойстве (кликни)</button>
<script>
    button2.onclick = function() {
        alert(this);
    };
</script>

danik.js 15.10.2014 08:41

А теперь добавляем вызов функции:


<button onclick='f(event)'>this в атрибуте (кликни)</button>
<button id="button2">this в свойстве (кликни)</button>
<script>
    function f(event) {
        alert(this);
    }
    button2.onclick = function(event) {
        f(event);
    };
</script>


Boolean_Type, осознал косяк?

danik.js 15.10.2014 08:44

Указываем контекст при вызове функции:

<button onclick='f.call(this, event)'>this в атрибуте (кликни)</button>
<script>
    function f(event) {
        alert(this);
    }
</script>

kostyanet 15.10.2014 12:59

Цитата:

Сообщение от Boolean_Type
Ф-ция же срабатывает лишь при наведении на li, => и this должен указывать на этот эл-т...

Ответ надо искать в спецификациях. Нафиг, просто знайте что инлайновые вызовы требуют явного присвоения аргументов (this,event). Так всегда было, лежи оно так вовек.

danik.js 15.10.2014 13:14

Цитата:

Сообщение от kostyanet
просто знайте что инлайновые вызовы требуют явного присвоения аргументов

А не-инлайновые что-ли не требуют?

danik.js 15.10.2014 13:15

Цитата:

Сообщение от kostyanet
Ответ надо искать в спецификациях

Ответ надо искать в ECMA, он не имеет вообще никакого отношения к HTML-атрибутам, и вообще HTML

kostyanet 15.10.2014 13:15

Все равно не понял почему, видимо так было задумано в эпоху зарождения браузеров со скриптами http://www.quirksmode.org/js/events_early.html

kostyanet 15.10.2014 13:16

Цитата:

Сообщение от danik.js
А не-инлайновые что-ли не требуют?

Не требуют. Браза без базаров подгоняет this.

danik.js 15.10.2014 13:24

Цитата:

Сообщение от kostyanet
Не требуют. Браза без базаров подгоняет this

То есть в примере поста #4 у тебя при клике на вторую кнопку показывает [object HTMLButtonElement] ?

Boolean_Type 15.10.2014 14:30

Цитата:

Сообщение от danik.js (Сообщение 335625)
А теперь добавляем вызов функции:


<button onclick='f(event)'>this в атрибуте (кликни)</button>
<button id="button2">this в свойстве (кликни)</button>
<script>
    function f(event) {
        alert(this);
    }
    button2.onclick = function(event) {
        f(event);
    };
</script>


Boolean_Type, осознал косяк?

По-моему, это то же, о чём писал я в вопросе, только чуть более наворочено) И так, и так в this - Window.

Boolean_Type 15.10.2014 14:35

Цитата:

Сообщение от danik.js (Сообщение 335664)
То есть в примере поста #4 у тебя при клике на вторую кнопку показывает [object HTMLButtonElement] ?

Неинлайновые передают this.
function f(event) {
        alert(this);
    }
    button2.onclick = function(event) {
        alert(this); //здесь покажет, kostyanet прав
        f(event); //а здесь нет, т.к. вызов не в контексте DOM-элемента
      
};

Boolean_Type 15.10.2014 14:47

Спасибо всем, кто отписался, дали ответ на сайте-учебнике:
Атрибут onclick создает в качестве обработчика анонимную функцию, а код который вставлен в значение атрибута выполняется в этой функции. Т.е.
onclick="f(event);"
эквивалентно

el.onclick = function() {
f(event);
}

Т.к. функция f вызывается просто так, а не в контексте чего-то, то в качестве this в ней будет глобальный объект.
Похоже, что так, как бы глупо это ни звучало. Хотя всё равно это неприятный момент с учётом того, что ф-ция срабатывает при определённом действии польз-ля, а не просто так.

Цитата:

Сообщение от kostyanet (Сообщение 335648)
Ответ надо искать в спецификациях. Нафиг, просто знайте что инлайновые вызовы требуют явного присвоения аргументов (this,event). Так всегда было, лежи оно так вовек.

Да, спасибо. Похоже, остаётся лишь смириться)

danik.js 15.10.2014 15:01

Ну вы укурки ))) Два укурка ))
Цитата:

Сообщение от Boolean_Type
onclick="f(event);"
эквивалентно
el.onclick = function() {
f(event);
}

А теперь выдохни и посмотри на код из http://javascript.ru/forum/events/50...tml#post335625 .
Ниче не напоминает ? :D
Цитата:

Сообщение от Boolean_Type
Да, спасибо. Похоже, остаётся лишь смириться)

Или перестать укуриваться ) Ибо нет никакой разницы инлайн-не инлайн. Повторяю для накуренных: JavaScript не завязан на HTML. Нет никакой разницы между функцией созданной из атрибута, и функцией, присвоенной в js коде. Функция - она и в африке функция. Запусти ее в африке - ничего не изменится.

Цитата:

Сообщение от Boolean_Type
onclick создает в качестве обработчика анонимную функцию

И еще пачку блоков with{}

terminator-101 15.10.2014 15:07

Цитата:

Сообщение от Boolean_Type
Но ведь в обоих случаях ф-ция является обработчиком СОБЫТИЯ на КОНКРЕТНОМ элементе, в чём же тут дело?

Функция не является ничем кроме функции. Это ты, почему-то называешь ее обработчиком чего-то там. А вопрос в чем, вообще непонятно. Вызов функции в топлевеле -- это всегда вызов в контексте window, в браузере. И ты, значит, спрашиваешь, почему this связывается с тем объектом, с которым должна связываться, а не с тем, с которым мне хотелось бы чтобы он связывался, в этом чтоли вопрос? С таким же успехом можно спросить, почему трава зеленого цвета, ведь мне хотелось бы, чтобы она была синяя.

terminator-101 15.10.2014 15:17

Цитата:

Сообщение от Boolean_Type
Похоже, что так, как бы глупо это ни звучало. Хотя всё равно это неприятный момент с учётом того

Все правильно, а глупо это звучит только для поциэнтов с жабой головного мозга в терминальной стадии. В JS Ъ-ООП в стиле смолтока, это куда более сильная модель чем статик-блядство в стиле лексических замыканий.

Boolean_Type 15.10.2014 17:12

Цитата:

Сообщение от terminator-101 (Сообщение 335690)
Функция не является ничем кроме функции.

Да что Вы говорите.
http://learn.javascript.ru/introduct...событий

Boolean_Type 15.10.2014 17:27

Цитата:

Сообщение от danik.js (Сообщение 335689)
Ну вы укурки ))) Два укурка ))

А теперь выдохни и посмотри на код из http://javascript.ru/forum/events/50...tml#post335625 .
Ниче не напоминает ? :D
Или перестать укуриваться ) Ибо нет никакой разницы инлайн-не инлайн. Повторяю для накуренных: JavaScript не завязан на HTML. Нет никакой разницы между функцией созданной из атрибута, и функцией, присвоенной в js коде.

Причём тут укуриваться, чё за манера? :nono:
Вот именно, напоминает, ибо ты написал то же самое, где вызов идёт не в контексте элемента, а контексте Window. Об этом и писал мне отвечающий.
Цитата:

Сообщение от danik.js (Сообщение 335689)
нет никакой разницы инлайн-не инлайн.

При инлайн надо явно передавать this в вызове!) Ты же сам видишь.
<button id="l" onclick="f();">инлайн-метод, не передаю this</button>
<button onclick="f(this);">инлайн-метод, передаю this</button>
<script type="text/javascript">
function f(obj_this){
    alert(this);
    alert(obj_this);
}
//здесь в вызове не передаётся this, но в ф-ции обработчики контекст устанавливается правильно, метод не инлайновый
document.getElementById('l').onmouseover = function (e) {
     console.log(this)
}
</script>

Накурился я или нет, а пример налицо. При инлайн-вызове надо просто this передавать, я запомню. И видна эта this будет лишь ф-ции, в кот-ую передаётся, а вот это говнище работать нормально не будет:
button2.onclick = function(event) {
   f(event);
};

т.к. внутри обработчика вызывается левая ф-ция в контексте Window. Вот это будет:
button2.onclick = function(event) {
   alert(this); //требуем this прямо в обработчике, а не посредством левой ф-ции
};

danik.js, меня отпустило :thanks:
Спасибо всем отписавшимся, вот бы на сайтах, пхп посвящённых, так же оперативно и с примерами отвечали...

danik.js 15.10.2014 17:37

Цитата:

Сообщение от Boolean_Type
При инлайн надо явно передавать this в вызове!) Ты же сам видишь.

Да блядь жеж! А при не-инлайн не надо чтоли? Ты троллишь чтоли? Покажи как ты в неинлайн обработчике вызываешь функцию f и не передаешь this, и в функции f this указывает не на window. Жду

danik.js 15.10.2014 17:39

Вот тебе функция f:
function f(event) {
alert(this);
}

danik.js 15.10.2014 17:42

Цитата:

Сообщение от Boolean_Type
console.log(this)

Ах ты хитрая жопа!!! Значит, в неинлайн ты логируешь тупо this в теле обработчика, в инлайн вызываешь какую-то левую? f()

И в чем тут логика?

danik.js 15.10.2014 17:43

Вот инлайн обработчик. Что блядь в нем не так? Куда там this не показывает?
<button onclick="console.log(this)">Button</button>

Boolean_Type 15.10.2014 17:44

Цитата:

Сообщение от danik.js (Сообщение 335754)
Да блядь жеж! А при не-инлайн не надо чтоли? Ты троллишь чтоли? Покажи как ты в неинлайн обработчике вызываешь функцию f и не передаешь this, и в функции f this указывает не на window. Жду

:lol:
Эй, а кому же я предыдущий пример печатал??? Вот кусок из него:
<button id="l">тут НЕ инлайн</button>
<script type="text/javascript">
//ещё раз, об этом Костянет писал тоже: здесь в вызове не передаётся this, но в ф-ции обработчики контекст устанавливается правильно, метод не инлайновый
document.getElementById('l').onclick = function () { //НИ ХЕРА НЕ ПЕРЕДАЮ
     alert(this); //ОХРЕНЕТЬ, this - это [object HTMLButtonElement]
}
</script>

Boolean_Type 15.10.2014 17:44

Цитата:

Сообщение от danik.js (Сообщение 335760)
Вот инлайн обработчик. Что блядь в нем не так? Куда там this не показывает?
<button onclick="console.log(this)">Button</button>

Да, тут показывает, ты же его явно передал. А в моём вопросе не показывал, ибо я не передал его явно :)

danik.js 15.10.2014 17:45

Цитата:

Сообщение от Boolean_Type
Да что Вы говорите.

И чем отличается обработчик от функции? Функция, когда ее назвали обработчиком, перестает быть функцией? Приобретает новые свойства?

danik.js 15.10.2014 17:47

Цитата:

Сообщение от Boolean_Type
Да, тут показывает, ты же его явно передал

Смотрим твой код:
Цитата:

Сообщение от Boolean_Type
document.getElementById('l').onmouseover = function (e) {
console.log(this)
}

А ну немедленно перестань передавать this в console.log() !:D

danik.js 15.10.2014 17:49

Цитата:

Сообщение от Boolean_Type
//НИ ХЕРА НЕ ПЕРЕДАЮ

Ты идиот. Что и куда тут можно передать? Ты записываешь функцию в свойство onclick
Онологично как я задаю атрибут onclick с телом функции.

danik.js 15.10.2014 17:51

Покажи, где тут разничия в поведении?
1)  <a onclick =                "       alert(this)      ">
2)    a.onclick = function() {       alert(this)      };

Boolean_Type 15.10.2014 17:52

Цитата:

Сообщение от danik.js (Сообщение 335759)
Ах ты хитрая жопа!!! Значит, в неинлайн ты логируешь тупо this в теле обработчика, в инлайн вызываешь какую-то левую? f()

И в чем тут логика?

:lol: danik.js, я не успеваю за твоими ответами)
Вот именно, я не понимал, почему при вызове левой f() контекст не передаётся. Я думал - раз событие, так this во всех ф-циях будет показываться, которые запущены этим событием. Ошибался.

Boolean_Type 15.10.2014 17:56

Цитата:

Сообщение от danik.js (Сообщение 335769)
Покажи, где тут разничия в поведении?
1)  <a onclick =                "       alert(this)      ">
2)    a.onclick = function() {       alert(this)      };

Тут их нет, ты же в строке this указал) А если чё-то типа <a onclick = "some_fucking_func()">, и в этой some_fucking_func прописано alert(this), этот this будет Window.

Ладно, danik.js, ну отстань уже, я разобрался :D

danik.js 15.10.2014 17:56

Корявые шрифты поломали вырванивание. Вот:

Boolean_Type 15.10.2014 17:57

Цитата:

Сообщение от danik.js (Сообщение 335774)
Корявые шрифты поломали вырванивание. Вот:

Нафиг стока пробелов, я и так понял, что там написано)))

danik.js 15.10.2014 17:58

Цитата:

Сообщение от Boolean_Type
А если чё-то типа <a onclick = "some_fucking_func()">, и в этой some_fucking_func прописано alert(this), этот this будет Window.

То есть если сделать так то будет какая-то разница? :


Мы ведь это уже проходили, только вместо some_fucking_func() было f(). У тя провалы в памяти?

Так будет разница или нет?

Boolean_Type 15.10.2014 18:01

Цитата:

Сообщение от danik.js (Сообщение 335776)
У тя провалы в памяти?

Так будет разница или нет?

А у тебя? Я же ответил выше.
http://javascript.ru/forum/events/50...tml#post335773

danik.js 15.10.2014 18:13

Цитата:

Сообщение от Boolean_Type
Я же ответил выше.

Ты не ответил. Дословно:
Цитата:

Сообщение от Boolean_Type
А если чё-то типа <a onclick = "some_fucking_func()">, и в этой some_fucking_func прописано alert(this), этот this будет Window.

То есть в варианте с атрибутом будет Window, а в варианте со свойством - что-то другое?
Можешь не гадать, я уже пример накидал: http://javascript.ru/forum/events/50...tml#post335625

Boolean_Type 15.10.2014 18:32

Цитата:

Сообщение от danik.js (Сообщение 335784)
я уже пример накидал: http://javascript.ru/forum/events/50...tml#post335625

Нахер такие переподвыподверты? Зачем из-под одной ф-ции было вызывать f(), этот пример нихрена не показателен, там Window везде, что ты им сказать-то пытался?
<button onclick='f(event)'>this в атрибуте (кликни)</button>
<button id="button2">this в свойстве (кликни)</button>
<script>
    function f(event) {
        alert(this);
    }
    button2.onclick = function(event) {
        alert(this); //нахер тут было f вызывать? Я уже понял, что там Window) И ты ещё говоришь, что я хитрая жопа?:D 
    };
</script>

terminator-101 15.10.2014 18:44

Boolean_Type,
А кто сказал, что там правильно написано?
f=function(){alert(this.foo)}
el1.onclick=f
el2.onhuy=f

Здесь f -- обработчик какого события, какого эдемента?

danik.js 15.10.2014 19:15

Цитата:

Сообщение от Boolean_Type
нахер тут было f вызывать?

А нахер в onclick="f()" вызывать f() ? :D

kostyanet 15.10.2014 21:12

danik.js, нахер вообще что-то вписываете? какие-то ивенты-шмывенты.

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

http://learn.javascript.ru/play/eG9lQ


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