web-dev-qa-db-ja.com

bindまたはclickでイベントハンドラをバインドしていない場合、<a>リンクをたどるためにjquery click()を呼び出すことはできますか?

JavaScriptにはタイマーがあり、時間が経過したらリンクをクリックして別のページに移動することをエミュレートする必要があります。これを行うために、私はjQueryのclick()関数を使っています。私は$().trigger()window.locationも使っています、そして3つすべてで意図したように動作させることができます。

私はclick()で奇妙な振る舞いをいくつか観察しましたが、何が起こり、何が起こるのか理解しようとしています。

私はこの質問で説明するすべてのものにFirefoxを使用していますが、他のブラウザでこれがどうなるかにも興味があります。

$('a').bind('click',fn)$('a').click(fn)を使ってイベントハンドラを設定していなければ、$('a').click()を呼び出しても何もしないようです。ブラウザは新しいページを読み込まないため、このイベントに対するブラウザのデフォルトハンドラは呼び出されません。

ただし、最初にイベントハンドラを設定した場合、イベントハンドラが何もしなくても、それは期待どおりに機能します。

$('a').click(function(){return true;}).click();

これは、あたかも自分自身をクリックしたかのように新しいページをロードします。

だから私の質問は二重です:私はどこかで間違って何かをしているので、この奇妙な行動ですか?そして、私が自分のハンドラを作成していない場合、なぜclick()を呼び出してもデフォルトの動作で何もしないのですか?

編集:

Hoffmanが私の結果を再現しようとしたときに決定したように、上記の結果は実際には起こりません。私が昨日観察した出来事の原因がわからないが、今日私はそれが私が質問で述べたものではなかったことを確信している。

その答えは、ブラウザでクリックを「偽造」することはできず、jQueryが行うことはすべてイベントハンドラを呼び出すことです。あなたはまだページを変えるのにwindow.locationを使うことができます、そしてそれは私のためにうまく働きます。

174
Mnebuerquo

興味深いことに、これはおそらくjQueryの「機能要求」(つまりバグ)です。 jQueryイベントを要素にバインドした場合、jQueryクリックイベントは、要素に対してクリックアクション(DOMではonClickイベントと呼ばれる)のみをトリガーします。 jQueryのメーリングリスト( http://forum.jquery.com/ )に行き、これを報告してください。これは望ましい振る舞いかもしれませんが、私はそうは思いません。

編集:

私はいくつかのテストをしました、そしてあなたが 'a'タグに関数を束縛したとしてもあなたが言ったことは間違っています、それでもhref属性によって指定されたウェブサイトにあなたを連れて行かない。次のコードを試してください。

<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script>
  $(document).ready(function() {
   /* Try to dis-comment this:
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }
 </script>

</head>
<body>
 <input type="button" onclick="button_onClick()">
 <br>
 <a id='a' href='http://www.google.com' onClick="a_onClick()"> aaa </a>

</body>
</html> 

あなたが直接リンクをクリックしない限り、それはgoogle.comに行くことは決してありません(コメント付きのコードの有無にかかわらず)。また、クリックイベントをリンクにバインドしても、ボタンをクリックしてもまだ紫色にならないことに注意してください。リンクを直接クリックした場合にのみ紫色になります。

私はいくつかの調査をしましたが、ブラウザがjavascriptで「偽のクリック」をサポートしていないため、.clickは 'a'タグで動作するとは想定されていないようです。つまり、JavaScriptで要素を「クリック」することはできません。 'a'タグを使用すると、onClickイベントを発生させることができますが、リンクの色は変わりません(訪問したリンクの色に変更します。ほとんどのブラウザのデフォルトは紫色です)。そのため、href属性に移動する動作はonClickイベントの一部ではなく、ブラウザにハードコードされているため、$()。clickイベントを 'a'タグで機能させることは意味がありません。

88
Hoffmann

別の選択肢はもちろんVanilla javascriptを使うことです:

document.getElementById("a_link").click()
239
Peter

$.click関数のコードを見れば、先に進む前に、その要素にclickイベントのリスナーが登録されているかどうかを確認する条件ステートメントがあると思います。リンクからhref属性を取得して手動でページの場所を変更しないのはなぜですか。

 window.location.href = $('a').attr('href');

編集:trigger関数から、バージョン1.3.2のjQueryソースをクリックスルーしない理由は次のとおりです。

 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
        event.result = false;

    // Trigger the native events (except for clicks on links)
    if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
        this.triggered = true;
        try {
            elem[ type ]();
        // prevent IE from throwing an error for some hidden elements
        } catch (e) {}
    }

それがハンドラを呼び出した後(もしあれば)、jQueryはオブジェクトのイベントを起動します。ただし、要素がリンクではない場合にのみクリックイベントのネイティブハンドラを呼び出します。これは何らかの理由で意図的に行われたと思います。これは、イベントハンドラが定義されているかどうかにかかわらず当てはまります。そのため、あなたの場合、イベントハンドラをアタッチするとネイティブのonClickハンドラが呼び出される理由がわかりません。あなたは私がしたことをしなければならず、そしてそれが呼ばれている場所を見るために実行を通して歩かなければなりません。

62
Ryan Lynch

アンカータグのクリックハンドラはjQueryの特別な場合です。

私はあなたがアンカーのonclickイベント(ブラウザによって知られている)とアンカータグのDOMの概念を包むjQueryオブジェクトのclickイベントの間で混乱しているかもしれないと思います。

JQuery 1.3.2のソースをダウンロードすることができます こちら

ソースの関連セクションは2643-2645行目です(分かりやすくするためにこれを複数の行に分割しました)。

// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;
5
marshally

Jqueryを接続したい要素の内側にあるHyperlink要素を起動します。

<div class="TopicControl">
    <div class="articleImage">
       <a href=""><img src="" alt=""></a>
    </div>
</div>

あなたのスクリプトで、あなたはクリックイベントが欲しいメインコンテナに接続します。次に、標準のjquery方法論を使用して要素(type、class、id)を見つけてクリックを起動します。 jqueryがクリックを起動するために再帰的関数を入力し、イベント 'e'とstopPropagation()関数を受け取ることで再帰的関数を中断し、jqueryがリンクを起動する以外に何もしたくないのでfalseを返します。

$('.TopicControl').click(function (event) {
         $(this).find('a').click();
        event.stopPropagation();
        return false;
     });

別の解決策は、コンテナを要素で囲み、の代わりにをコンテナの中に入れることです。 w3c規格に準拠するようにスパンを表示ブロックに設定します。

3
Paul Styles

JS/jQueryは、プログラムで「クリック」されたリンクのデフォルトの動作をサポートしません。

できることは、フォームを作成して送信することです。これにより、ブラウザによって不要なポップアップとしてブロックされることが多いwindow.locationwindow.openを使用する必要がなくなります。

このスクリプトには2つの異なる方法があります。1つは3つの新しいタブ/ウィンドウを開くことを試みるもので(これはIEとChromeで1つだけ開きます)。

方法は次のとおりです。

HTML

<html>
<head>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
    <button id="testbtn">Test</button><br><br>

    <a href="https://google.nl">GOOGLE</a><br>
    <a href="http://en.wikipedia.org/wiki/Main_Page">WIKI</a><br>
    <a href="https://stackoverflow.com/">SO</a>
</body>
</html>

jQuery(script.js)

$(function()
{ 
    // Try to open all 3 links by pressing the button
    // - Firefox opens all 3 links
    // - Chrome only opens 1 of them without popup warning
    // - IE only opens 1 of them WITH popup warning
    $("#testbtn").on("click", function()
    {
        $("a").each(function()
        {
            var form = $("<form></form>");
            form.attr(
            {
                id     : "formform",
                action : $(this).attr("href"),
                method : "GET",
                // Open in new window/tab
                target : "_blank"
            });

            $("body").append(form);
            $("#formform").submit();
            $("#formform").remove();
        });
    });

    // Or click the link and fire a custom event 
    // (open your own window without following the link itself)
    $("a").on("click", function()
    {
        var form = $("<form></form>");
        form.attr(
        {
            id     : "formform",
            // The location given in the link itself
            action : $(this).attr("href"), 
            method : "GET",
            // Open in new window/tab
            target : "_blank"              
        });

        $("body").append(form);
        $("#formform").submit();
        $("#formform").remove();

        // Prevent the link from opening normally
        return false;
    });

});

これは各link要素に対して行われます。

  1. フォームを作成する
  2. 属性を与える
  3. 送信できるようにDOMに追加します
  4. それを提出する
  5. すべてのトレースを削除して、DOMからフォームを削除します。*邪悪な笑いを挿入*

これで"https://google.nl"をロードする新しいタブ/ウィンドウができました。残念ながら、この方法で複数のウィンドウを開こうとすると、2番目のウィンドウを開こうとするとPopup blockedメッセージバーが表示されます(最初のウィンドウはまだ開いています)。


私がこの方法をどのようにして得たかに関するさらなる情報はここにあります:

window.openまたはwindow.location.hrefを使用せずに新しいウィンドウ/タブを開く

3
Richard de Wit

この機能が必要な場合は1つのケース、またはごく少数のケースがあります。 (あなたはアプリ全体がこの機能を必要としていない)jQueryをそのままにして(より新しいバージョンへのアップデート、CDNなどを含む多くの理由から)、次の回避策を持っていたいと思います。

// For modren Browsers
$(ele).trigger("click");

// Relaying on Paul Irish's conditional class names http://bit.ly/HWIpAp (via HTML5 Boilerplate http://bit.ly/HUzi3I) where each IE version gets a class of its Version
$("html.ie7").length && (function(){
    var eleOnClickattr = $(ele).attr("onclick") 
    eval(eleOnClickattr);
  })()
2
adardesign

イベントがイベントにバインドされていないため、何もしません。私が正しく思い出したならば、jQueryはパフォーマンスと他の目的のためにNodeListsに縛られるイベントハンドラのそれ自身のリストを維持します。

2
JasonWyatt

同じタブでハイパーリンクを開くには、次のようにします。

$(document).on('click', "a.classname", function() {
    var form = $("<form></form>");
    form.attr(
    {
        id     : "formid",
        action : $(this).attr("href"),
        method : "GET",
    });

    $("body").append(form);
    $("#formid").submit();
    $("#formid").remove();
    return false;
});
1

JQueryを使用して、その要素のjQueryオブジェクトを選択できます。次に、基礎となるDOM要素を取得して、そのclick()メソッドを呼び出します。

iDで

$("#my-link").each(function (index) { $(this).get(0).click() });

またはjQueryを使ってCSSクラスごとにたくさんのリンクをクリックする

$(".my-link-class").each(function (index) { $(this).get(0).click() });
1
10GritSandpaper