fastclickを記録していますが、手動でclickイベントをトリガすることに失敗しました.
3188 ワード
昨日のモバイル端末のプロジェクトにfastclickを導入した後、手動でclick事件を触発しました.文書を調べても解決方法が見つからず、最後にfastclickソースを見て解決しました.途中の文字を見たくないなら、直接最後まで訳して結論を見ることができます.
事故現場を復元する
実現したい機能は、div 1をクリックする時に手動でinputのclickイベントをトリガします.コードは以下の通りです
コードは以下の通りです
根源を追跡し,問題の原因の核心を捜し出す.
ソースを見てから、前の疑問に答えられます.
1、なぜアンドロイドは正常に仕事ができますか?
コード:
2、なぜiOSはマニュアルで二回のclickイベントをトリガしなければならないのですか?
これが今回の「事故」の鍵となります.クリックした時に単語clickイベントが発生しました.その中で初めてdivをクリックするために触発されました.その後2回は手動でinputのclickイベントを触発しました.
初めてのclick事件の時、fastclickはontouch Startでtarget Elementをdiv 1に設定しました.今回はsendClickを成功に実行しました.目標は私達が欲しいinputではありません.
続いて、初めて手動でclickイベントを触発しましたが、element.click関数によって手動で触発されましたので、ontouch Startというプロセスがありません.この時、target Elementはもちろんdiv 1です.このときneedsClickはfalseに戻り、onClickのonMouse関数もfalseに戻り、イベントを終了し、その後、target Elementをnullにします.
第二の手動clickイベントでは、この時点でtarget Elementはnullであるため、onMouseでtrueに戻り、その後、元のclickイベントをスムーズにトリガしました.
初めて手動でclick()を実行した時、この時のtagetElementはdiv 1で、即ちクリックした時の要素です.needsclickをinputに結び付けましたので、当然、tagetElement上でneedsclickが見つけられませんでした.この時も問題を解決する方法を見つけました.needsclickをdiv 1、すなわち実際にクリックした要素に結び付けます.
結論と収穫元のclickイベントをトリガしたい場合は、needsclickを実際にクリックした要素に結びつけてください.つまり、e.targe上であり、手動でトリガした要素ではありません.これはfastclickの小さいバグと言えます.前のクリックが後のクリックに影響を与えました. は、clickのコールバック関数の中で、手動でelement.click()をトリガすることしかできません.そうでなければ、無効です.興味のあるものは試してみてもいいです.これはMDNに書いてないので、意外な収穫です.
事故現場を復元する
実現したい機能は、div 1をクリックする時に手動でinputのclickイベントをトリガします.コードは以下の通りです
export default {
methos: {
handleClick() {
this.$refs.input.click()
}
}
}
fastclickを導入していない場合は、予想通りに作業ができます.導入後はAndroidでも正常に動作しますが、iOSではどうしてもできません.inputラベルにneedsclick類をつけてもだめです.不思議なことに、連続して手動で二回のclickイベントを触発すれば、iOSで正常に動作することができます.コードは以下の通りです
handleClick() {
this.$refs.input.click()
this.$refs.input.click()
}
考えてみれば、fastclickにしか理由がないです.まず文書を見ました.解決方法が見つからないので、ソースを見に行くしかないです.初めてfastclickを使った時コードを読んだことがありますが、当時は大体原理を実現するために普通に読みました.今回はもう一度見ました.ソースコードの解読はネット上にたくさんあります.ここで詳しく説明しません.コードは長くないので、自分で読んだほうがいいと思います.根源を追跡し,問題の原因の核心を捜し出す.
ソースを見てから、前の疑問に答えられます.
1、なぜアンドロイドは正常に仕事ができますか?
コード:
if (deviceIsAndroid) {
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport) {
// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
return true;
}
// Chrome 32 and above with width=device-width or less don't need FastClick
if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
// Chrome desktop doesn't need FastClick (issue #15)
} else {
return true;
}
fastclickが運行している時にfastclickを使う必要があるかどうかを判断します.私のAndroidテスト機chromeは32より大きいです.width=device-widthを設置しました.だからアンドロイドの下で使用していた生clickイベントをクリックすれば大丈夫です.2、なぜiOSはマニュアルで二回のclickイベントをトリガしなければならないのですか?
これが今回の「事故」の鍵となります.クリックした時に単語clickイベントが発生しました.その中で初めてdivをクリックするために触発されました.その後2回は手動でinputのclickイベントを触発しました.
初めてのclick事件の時、fastclickはontouch Startでtarget Elementをdiv 1に設定しました.今回はsendClickを成功に実行しました.目標は私達が欲しいinputではありません.
続いて、初めて手動でclickイベントを触発しましたが、element.click関数によって手動で触発されましたので、ontouch Startというプロセスがありません.この時、target Elementはもちろんdiv 1です.このときneedsClickはfalseに戻り、onClickのonMouse関数もfalseに戻り、イベントを終了し、その後、target Elementをnullにします.
第二の手動clickイベントでは、この時点でtarget Elementはnullであるため、onMouseでtrueに戻り、その後、元のclickイベントをスムーズにトリガしました.
if (!this.targetElement) {
return true;
}
3、なぜinputタグにneedsclickを付けてもclickイベントを成功させることができませんか?初めて手動でclick()を実行した時、この時のtagetElementはdiv 1で、即ちクリックした時の要素です.needsclickをinputに結び付けましたので、当然、tagetElement上でneedsclickが見つけられませんでした.この時も問題を解決する方法を見つけました.needsclickをdiv 1、すなわち実際にクリックした要素に結び付けます.
結論と収穫