onclick と addeventlistener の実行順
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ プロパティつけたタイミングで addEventListener 設定したのと同じ
◆ Chrome はプロパティ変更時に remove して add したように再設定される
◆ Firefox/IE は順番はそのままで null を設定したときに remove になる
◆ Chrome はプロパティ変更時に remove して add したように再設定される
◆ Firefox/IE は順番はそのままで null を設定したときに remove になる
addEventListener は同じ条件のリスナの場合はリスナをつけた順で処理されます
優先度をつけたりあとから並び替えたりはできません
全部 remove してソートして add すれば可能です
addEventListener 以外にも onclick のような onXXX 系プロパティに値をセットすることでもリスナを設定できます
onXXX と addEventListener が組み合わさるとどんな順番になるの?っと疑問に思ったので試してみました
↓は Chrome で実行してます
onclick プロパティに値をセットしたタイミングで addEventListener をつけたような動きです
onclick を再設定すると実行順番があとになります
次に Firefox と IE11 です
これらは最初に設定した場所にずっと固定されます
onclick を再設定しても順番は変わりません
ただし null を一度設定すれば removeEventListener されたような動きになってその後再設定すると順番が変わります
素直に設定ごとに remove/add しています
null 以外の付け替えで順番が変わらないのでリスナ自体はそのままでリスナから呼び出す関数を書き換えている感じです
優先度をつけたりあとから並び替えたりはできません
全部 remove してソートして add すれば可能です
addEventListener 以外にも onclick のような onXXX 系プロパティに値をセットすることでもリスナを設定できます
onXXX と addEventListener が組み合わさるとどんな順番になるの?っと疑問に思ったので試してみました
↓は Chrome で実行してます
const elem = document.body
const log = x => _ =>console.log(x)
elem.addEventListener("click", log(1))
elem.onclick = log("onclick")
elem.addEventListener("click", log(2))
// click: 1, onclick, 2
elem.onclick = log("onclick2")
// click: 1, 2, onclick2
elem.addEventListener("click", log(3))
// click: 1, 2, onclick2, 3
const log = x => _ =>console.log(x)
elem.addEventListener("click", log(1))
elem.onclick = log("onclick")
elem.addEventListener("click", log(2))
// click: 1, onclick, 2
elem.onclick = log("onclick2")
// click: 1, 2, onclick2
elem.addEventListener("click", log(3))
// click: 1, 2, onclick2, 3
onclick プロパティに値をセットしたタイミングで addEventListener をつけたような動きです
onclick を再設定すると実行順番があとになります
次に Firefox と IE11 です
これらは最初に設定した場所にずっと固定されます
onclick を再設定しても順番は変わりません
ただし null を一度設定すれば removeEventListener されたような動きになってその後再設定すると順番が変わります
内部処理のイメージ
実際の内部の処理は知らないですがこんな感じの動きになりますChrome
Object.defineProperty(element, "onclick", {
set(value){
this.removeEventListener("click", this._onclick)
this._onclick = value
value && this.addEventListener("click", value)
}
})
set(value){
this.removeEventListener("click", this._onclick)
this._onclick = value
value && this.addEventListener("click", value)
}
})
素直に設定ごとに remove/add しています
Firefox/IE11
const listener = function(eve){return this["_on" + eve.type](eve)}
Object.defineProperty(element, "onclick", {
set(value){
if(value){
if(!this._onclick) this.addEventListener("click", listener)
}else{
if(this._onclick) this.removeEventListener("click", listener)
}
this._onclick = value
}
})
Object.defineProperty(element, "onclick", {
set(value){
if(value){
if(!this._onclick) this.addEventListener("click", listener)
}else{
if(this._onclick) this.removeEventListener("click", listener)
}
this._onclick = value
}
})
null 以外の付け替えで順番が変わらないのでリスナ自体はそのままでリスナから呼び出す関数を書き換えている感じです