私は私が抱えているこの奇妙な問題を理解しようとしています、そして根本的な原因はライブクリックとトリガー.click()
の違いです。
問題の詳細については説明しませんが、基本的に入力ボタンをクリックすると正常に機能します(onclick
イベントがあります)。しかし、(ボタンを物理的にクリックする代わりに)別の場所から.click()
を呼び出すと、正しく機能しません。
私の質問は-ボタンの実際のクリックを本当に再現する方法はありますか?
[〜#〜]編集[〜#〜]
問題:インラインPDFをロードする新しいウィンドウ(aspxページ)を開いています。 実際にリンクをクリックすると、ウィンドウが正常に開き、PDFが読み込まれます。.click()
を使用すると、ウィンドウが開き、ダウンロードするように求められます。 PDFファイル。プロンプトについてAdobe Readerの設定、ブラウザーの設定、およびレジストリの設定を確認しました。これらが全体像の要因になる可能性があることは理解していますが、現時点ではマウスクリックと.click()の間の動作がまったく異なることをしている理由が心配です。
私はこの関数を使用して、マウスクリックを真に模倣します。
function clickLink(link) {
var cancelled = false;
if (document.createEvent) {
var event = document.createEvent("MouseEvents");
event.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0,
false, false, false, false,
0, null);
cancelled = !link.dispatchEvent(event);
}
else if (link.fireEvent) {
cancelled = !link.fireEvent("onclick");
}
}
問題を回避する方法について説明している以下を読む前に、最初に問題が発生している理由を詳しく説明します。
最近のブラウザは、どのマウスボタンをクリックしたか、押したままかどうかなどに基づいて、リンクに対してさまざまなアクションを実行します。 Shift / Ctrl / Alt、 等々。たとえば、Chromeでは、左クリックではなくリンクを中クリックすると、ブラウザは自動的に新しいタブでウィンドウを開きます。
.click()
を使用する場合、jQueryは、クリックした「方法」について想定する必要があります。デフォルトの動作が発生しますが、これは正しい動作ではありません。この問題を修正するには、ブラウザにMouseEvents
設定の形式で「正しい」設定を指定する必要があります。
次に、それを修正する方法について簡単に説明します。
パラメータなしでjQueryの.click()
イベントを使用している場合、これは実際には問題の要素を「クリックを偽造」しているわけではありません。代わりに、 http://api.jquery.com/click/ のjQueryドキュメントによると:
...
.click()
が引数なしで呼び出された場合、それは.trigger( "click")のショートカットです。
つまり、$('#div1').click()
を起動すると、_'click'
_イベントの実際のjQueryハンドラーがない場合、デフォルトの処理が行われます。したがって、次の2つのケースを検討してください。
ケース1:
_<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
$('#myLink').click();
</script>
_
この最初のシナリオでは、.click()
呼び出しは、そのハンドラーがないため、何もしません。イベントはトリガーされますが、それをキャッチして応答するものはありません-したがって、a
タグのデフォルトの処理が使用され、ユーザーは_/some/link/
_に移動します-マウスボタンを指定していないためまたは他のパラメータ-それは本当にデフォルトです。
ケース2:
_<a id='myLink' href='/some/link/'>Click me!</a>
<script type='text/javascript'>
$('#myLink').bind('click', function (ev) {
ev.preventDefault();
ev.stopPropagation();
alert('you clicked me!');
}).click();
</script>
_
このシナリオでは、click
ハンドラーが作成されたため、ユーザーがリンクをクリックすると、ev.preventDefault()
およびev.stopPropagation()
呼び出しにより、デフォルトの処理が停止され、警告が発せられます。
ただし、この時点で、ev
を表すMouseEvents
オブジェクトがあり、必要に応じて設定を変更できます。たとえば、次のようにすることができます。
_ev.altKey = true; // Held Alt
ev.button = 1; // Middle Mouse Button
_
これらの設定により、イベントを処理するデフォルトの方法が変更されます。
代替の非jQueryソリューション
次のコードを適用することで、ボタンクリックを実際にシミュレートすることもできます。
_function fakeClick(event, anchorObj) {
if (anchorObj.click) {
anchorObj.click()
} else if(document.createEvent) {
if(event.target !== anchorObj) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var allowDefault = anchorObj.dispatchEvent(evt);
// you can check allowDefault for false to see if
// any handler called evt.preventDefault().
// Firefox will *not* redirect to anchorObj.href
// for you. However every other browser will.
}
}
}
_
(より完全な実装については、元の投稿を参照してください: アンカータグへのクリックをシミュレートするにはどうすればよいですか? -そして選択した回答を見てください)
これにより、実際には、ブラウザのデフォルトハンドラと同じ方法でイベントを最初から作成することにより、アンカー/スパンなどをマウスでクリックしたとブラウザに誤解させます。ただし、一部の設定を上書きできます。ただし、このアプローチは、クロスブラウザーアプリケーションで破損する可能性がはるかに高く、すべてのパラメーターが何にマップされるかを把握する必要があるため、お勧めしません。
$('img').click(function(event){
console.log(event.hasOwnProperty('originalEvent')); // output : true
});
$('img').trigger("click",function(event){
console.log(event.hasOwnProperty('originalEvent')); // output : false
});
ユーザークリックと同じクリックイベントを作成してトリガーするには:
function simulateClick() {
var event = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
var cb = document.getElementById('checkbox'); //whichever element you want to click
var cancelled = !cb.dispatchEvent(event);
if (cancelled) {
// A handler called preventDefault.
alert("cancelled");
} else {
// None of the handlers called preventDefault.
alert("not cancelled");
}
}
もちろん、このような関数を呼び出します。
simulateClick();
ソース: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
注:initMouseEvent()は非推奨です。このソリューションで示されているように、使用を避け、代わりにMouseEvent()を使用してください。