onclick関数で「this」参照を保持しながら、アンカータグからonclick()イベントをプログラムで呼び出すにはどうすればよいですか?


83

以下は機能しません...(少なくともFirefoxでは:document.getElementById('linkid').click()機能ではありません)

<script type="text/javascript">
    function doOnClick() {
        document.getElementById('linkid').click();
        //Should alert('/testlocation');
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>

回答:


110

applyその要素のコンテキストでイベントハンドラーを実行する必要があります。

var elem = document.getElementById("linkid");
if (typeof elem.onclick == "function") {
    elem.onclick.apply(elem);
}

それ以外の場合thisは、上記のコードが実行されるコンテキストを参照します。


3
私をばかだと思っていないのはあなただけだと思います(角かっこ表記/ onclick | clickブラウザの非互換性について言及していないため)。スポットオン!
Ropstah 2009年

3
これを考慮してください:howtocreate.co.uk/tutorials/javascript/domevents-onclick関数を呼び出すと、登録されているすべてのイベントハンドラーが呼び出されますか?また、イベントを誤って呼び出すと、そのイベントに関連付けられたデフォルトのアクション(フォームの送信など)は生成されません。
jrharshath 2009年

ガンボ、このコードは
異なる

1
なぜapply()ここで使うのですか?あなただけ行うことができelem.onclick();、およびelem機能の「この」リファレンスになります-シンプル!
ドゥーイン

18

これを解決する最善の方法はVanillaJSを使用することですが、すでにjQueryを使用している場合は、非常に簡単な解決策があります。

<script type="text/javascript">
    function doOnClick() {
        $('#linkid').click();
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>

IE8-10、Chrome、Firefoxでテスト済み。


3
なぜ反対票を投じるのですか?理由をコメントしてください。何かがおかしいと思われる場合は、質問を改善できます。
luschn 2016

1
スタックオーバーフローには、OPが質問で明示的に言及していない場合、外部リソース(jQueryなどのライブラリなど)に依存する回答を提供するべきではないと述べられています。それが反対票の動機となったと思います
vhoyer

2013年には、誰もがjqueryを使用していましたが、最近は同意します:)-将来の参考のために答えを残しておきます。
luschn

15

イベントをトリガーするには、基本的にその要素のイベントハンドラーを呼び出すだけです。コードからわずかな変更。

var a = document.getElementById("element");
var evnt = a["onclick"];

if (typeof(evnt) == "function") {
    evnt.call(a);
}

1
+1。また、少しグーグルすると、foo.click()はIEのみであることが
わかり

1
角かっこ表記(["onclick"])ではな​​く、ドット表記(.onclick)を使用する必要があります。
Rudd Zwolinski 2009年

.onclick()または.click()はどちらも期待どおりに機能しません。Firefox .click(または括弧で囲まれた['click'])では、「NOTAFUNCTION」です。しかし、.onclick()を呼び出すと、「this」参照が失われます(実行関数で<a>タグからの情報が必要なため、ASP.NET MVCでこれが必要です)
Ropstah 2009年

5
$("#linkid").trigger("click");

2
SOへようこそ。これが機能する理由(正確には何が機能するかなど)と、これが他のソリューションと異なる点について詳しく教えてください。
m00am 2015年

2
なぜこの答えをマークダウンするのですか?jqueryを使用する場合、これはこのページの最良の解決策です... 1つのライナー-それを打ち負かすことはできません!
PodTech.io 2016年

答えはjQueryを必要とすべきではありません
Greg Perham

5

確かに、OPはこれはうまくいかなかったと非常によく似ていますが、私にとってはうまくいきました。私の情報源のメモに基づくと、OPの投稿の前後、またはその後に実装されたようです。おそらく、今ではもっと標準的です。

document.getElementsByName('MyElementsName')[0].click();

私の場合、ボタンにIDがありませんでした。要素にIDがある場合は、できれば次のものを使用してください(テストされていません)。

document.getElementById('MyElementsId').click();

私はもともとこの方法を試しましたが、うまくいきませんでした。グーグルした後、私は戻ってきて、自分の要素が名前であり、IDを持っていないことに気づきました。正しい属性を呼び出していることを再確認してください。

ソース:https//developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click


1

handleEventメソッド
https://developer.mozilla.org/en-US/docs/Web/API/EventListenerをご覧ください

「生の」Javascript:

function MyObj() {
   this.abc = "ABC";
}
MyObj.prototype.handleEvent = function(e) {
   console.log("caught event: "+e.type);
   console.log(this.abc);
}

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj);

次に、要素(IDが「myElement」)をクリックすると、コンソールに次のように出力されます。

キャッチされたイベント:
ABCをクリックします

これにより、オブジェクトメソッドをイベントハンドラーとして使用し、そのメソッドのすべてのオブジェクトプロパティにアクセスできます。

オブジェクトのメソッドをaddEventListenerに直接渡して(次のように)、通常はオブジェクトで呼び出されたかのように動作することを期待することはできません。addEventListenerに渡された関数は、参照されるのではなく、何らかの形でコピーされていると思います。たとえば、イベントリスナー関数参照を(変数の形式で)addEventListenerに渡してから、この参照の設定を解除すると、イベントがキャッチされたときにイベントリスナーが実行されます。element.addEventListener('click',myObj.myMethod);myMethod

メソッドをイベントリスナーおよびstilとして渡し、イベントリスナーthis内のオブジェクトプロパティにアクセスできるようにする別の(あまりエレガントではない)回避策 は、次のようになります。

// see above for definition of MyObj

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj.handleEvent.bind(myObj));

1

古いスレッドですが、質問はまだ関連しているので...

(1)あなたの質問の例では、今DOES Firefoxで仕事を。しかし、(警告を表示)イベントハンドラを呼び出すことに加えて、それがALSO(アラートが却下された後)ナビゲーションを引き起こし、リンクをクリック。

(2)〜JUSTは:単に置き換える(ナビゲーションをトリガすることなく)イベントハンドラを呼び出します

document.getElementById('linkid').click();

document.getElementById('linkid').onclick();

0

これを純粋にonclick属性の関数を参照するために使用している場合、これは非常に悪い考えのように思われます。インラインイベントは一般的に悪い考えです。

私は次のことを提案します:

function addEvent(elm, evType, fn, useCapture) {
    if (elm.addEventListener) {
        elm.addEventListener(evType, fn, useCapture);
        return true;
    }
    else if (elm.attachEvent) {
        var r = elm.attachEvent('on' + evType, fn);
        return r;
    }
    else {
        elm['on' + evType] = fn;
    }
}

handler = function(){
   showHref(el);
}

showHref = function(el) {
   alert(el.href);
}

var el = document.getElementById('linkid');

addEvent(el, 'click', handler);

他のJavaScriptコードから同じ関数を呼び出したい場合、クリックして関数を呼び出すことをシミュレートすることは最善の方法ではありません。考えてみましょう:

function doOnClick() {
   showHref(document.getElementById('linkid'));
}

'this'への参照を維持することです。アンカー(.NET MVC)でonclickパーツを生成するだけでは不十分です。完全なアンカータグを生成する必要があります。このタグは、onclick関数で完全に必要です(たとえば、href属性を使用します)。
Ropstah 2009年

-1

一般に、イベントハンドラーを「手動で」呼び出すことはお勧めしません。

  • 複数のリスナーが登録されているため、何が実行されるかは不明です
  • 再帰的で無限のイベントループに入る危険性(クリックAがクリックBをトリガーし、クリックAがトリガーされるなど)
  • DOMの冗長な更新
  • ユーザーによって引き起こされたビューの実際の変更と、初期化コードとして行われた変更(1回だけ実行する必要があります)を区別するのは困難です。

より良いのは、何をしたいのかを正確に把握し、それを関数に入れて手動で呼び出し、イベントリスナーとして登録することです。


OPは、何かをするための最良の方法ではなく、何かをする方法を尋ねました。これはCodeReviewではありません。もしあなたが彼の質問に答えてから免責事項を書いていたら、それは違うでしょう。
タイラーモンニー2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.