iPhone用のサイトをコーディングしているとき、
document や body にクリックイベントを設定してもイベントが発火しないという現象に陥ったことはないでしょうか。
ざっと調べてみるとどうやら、document、bodyにはクリックイベントが設定できないようです。
ただし、イベントの伝播を使えば発火させることはできるようで、クリックイベントを持った子要素をクリックすることで、documentやbodyに対してのクリックイベントを発火させることができます。
(function(win, doc) { "use strict"; doc.querySelector("div").addEventListener("click", function() { alert("div"); }, false); doc.addEventListener("click", function() { alert("document"); }, false); doc.write("DOCUMENT"); })(this, document);
※ iPhoneでみてみてください。
上記例だと、div要素とdocumentのバブリングフェーズにクリックイベントを設定していますが、
- documentを直接タップしてもクリックイベントが発火しない。
- div要素をタップすると、div要素のクリックイベント → documentのクリックイベントの順に発火する。
ということがわかります。
若干余談ですが、もしdiv要素をクリックした際のイベントの発火順を逆にしたければ、
(function(win, doc) { "use strict"; doc.querySelector("div").addEventListener("click", function() { alert("div"); }, false); doc.addEventListener("click", function() { alert("document"); }, true); // キャプチャリングフェーズに変更 doc.write("DOCUMENT"); })(this, document);
と、documentへのaddEventListenerの第3引数をtrueにすることによって調整できます。
また、子要素にはクリックイベントさえ張っておけば、documentのクリックイベントは発火するようになるので、
(function(win, doc) { "use strict"; doc.querySelector("div").addEventListener("click", function(evt) { ; // なにもしない }, false); doc.addEventListener("click", function() { alert("document"); }, true); doc.write("DOCUMENT"); })(this, document);
と、div要素になにも起こらないクリックイベントを設定するだけでも、documentのクリックイベントが発火するようになります。
上記例では、空のクリックイベントを設定したdiv要素を全面に敷いているので、documentをクリックした際にクリックイベントが発火している風になっています。
【追記】
続・iPhoneのMobile Safariでdocumentに設定したクリックイベントが効かないときの対処法 - みかづきブログ その3