ฉันสามารถโทร jquery click () เพื่อติดตามลิงก์ <a> ได้หรือไม่หากฉันไม่ได้ผูกตัวจัดการเหตุการณ์ไว้ด้วยการผูกหรือคลิกแล้ว


175

ฉันมีตัวจับเวลาใน JavaScript ของฉันซึ่งจำเป็นต้องเลียนแบบการคลิกลิงก์เพื่อไปยังหน้าอื่นเมื่อเวลาผ่านไป เมื่อต้องการทำสิ่งนี้ฉันใช้click()ฟังก์ชันของ jQuery ฉันได้ใช้$().trigger()และwindow.locationยังและฉันสามารถทำให้มันทำงานตามที่ตั้งใจไว้กับทั้งสาม

ฉันสังเกตเห็นพฤติกรรมแปลก ๆ ด้วยclick()และฉันพยายามที่จะเข้าใจว่าเกิดอะไรขึ้นและทำไม

ฉันใช้ Firefox สำหรับทุกสิ่งที่ฉันอธิบายในคำถามนี้ แต่ฉันก็สนใจในสิ่งที่เบราว์เซอร์อื่นจะทำกับสิ่งนี้

หากฉันไม่ได้ใช้$('a').bind('click',fn)หรือ$('a').click(fn)ตั้งค่าตัวจัดการเหตุการณ์การโทร$('a').click()ดูเหมือนจะไม่ทำอะไรเลย ไม่เรียกตัวจัดการเริ่มต้นของเบราว์เซอร์สำหรับเหตุการณ์นี้เนื่องจากเบราว์เซอร์ไม่โหลดหน้าใหม่

อย่างไรก็ตามถ้าฉันตั้งค่าตัวจัดการเหตุการณ์ก่อนมันก็ใช้ได้ตามที่คาดไว้แม้ว่าตัวจัดการเหตุการณ์จะไม่ทำอะไรเลย

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

สิ่งนี้จะโหลดหน้าใหม่ราวกับว่าฉันคลิกตัวเอง

ดังนั้นคำถามของฉันคือทวีคูณ: นี่เป็นพฤติกรรมแปลก ๆ เพราะฉันทำอะไรผิดไปหรือเปล่า? และทำไมการโทรถึงไม่click()ทำอะไรเลยกับพฤติกรรมเริ่มต้นหากฉันไม่ได้สร้างตัวจัดการเอง

แก้ไข:

ตามที่ฮอฟแมนกำหนดเมื่อเขาพยายามทำซ้ำผลลัพธ์ของฉันผลลัพธ์ที่ฉันอธิบายไว้ข้างต้นจะไม่เกิดขึ้นจริง ฉันไม่แน่ใจว่าสิ่งที่ทำให้เกิดเหตุการณ์ที่ฉันสังเกตเห็นเมื่อวานนี้ แต่ฉันมั่นใจในวันนี้ว่ามันไม่ใช่สิ่งที่ฉันอธิบายในคำถาม

ดังนั้นคำตอบคือคุณไม่สามารถคลิก "ปลอม" ในเบราว์เซอร์ได้และ jQuery ทั้งหมดจะเรียกใช้ตัวจัดการเหตุการณ์ของคุณ คุณยังคงสามารถใช้window.locationเพื่อเปลี่ยนหน้าและทำงานได้ดีสำหรับฉัน


2
อาจเป็นวิธีการแก้ปัญหา: stackoverflow.com/questions/31687759/…
Sukrit Chhabra

คำตอบ:


90

น่าสนใจนี่อาจเป็น "คำขอคุณลักษณะ" (เช่นข้อบกพร่อง) สำหรับ jQuery เหตุการณ์การคลิก jQuery จะกระตุ้นการคลิกเท่านั้น (เรียกว่าเหตุการณ์ onClick บน DOM) บนองค์ประกอบหากคุณผูกเหตุการณ์ jQuery กับองค์ประกอบ คุณควรไปที่รายชื่อผู้รับจดหมาย 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.co.th เว้นแต่คุณจะคลิกที่ลิงก์โดยตรง (โดยมีหรือไม่มีรหัสที่มีความคิดเห็น) นอกจากนี้โปรดสังเกตว่าแม้ว่าคุณจะผูกเหตุการณ์คลิกไปที่ลิงก์ แต่ก็ยังไม่เป็นสีม่วงเมื่อคุณคลิกปุ่ม มันจะไปสีม่วงถ้าคุณคลิกลิงก์โดยตรง

ฉันได้ทำการวิจัยและดูเหมือนว่า. คลิกไม่ควรทำงานกับแท็ก 'a' เพราะเบราว์เซอร์ไม่สนับสนุน "การคลิกปลอม" ด้วย javascript ฉันหมายความว่าคุณไม่สามารถ "คลิก" องค์ประกอบด้วยจาวาสคริปต์ ด้วยแท็ก 'a' คุณสามารถทริกเกอร์เหตุการณ์ onClick ได้ แต่ลิงก์จะไม่เปลี่ยนสี (เป็นสีของลิงก์ที่เข้าชมค่าเริ่มต้นคือสีม่วงในเบราว์เซอร์ส่วนใหญ่) ดังนั้นจึงไม่สมเหตุสมผลที่จะสร้าง $ () คลิกเหตุการณ์ทำงานกับแท็ก 'a' เนื่องจากการกระทำไปที่แอตทริบิวต์ href ไม่ใช่ส่วนหนึ่งของเหตุการณ์ onClick แต่เป็นการเข้ารหัสในเบราว์เซอร์


7
ฉันลองใช้รหัสของคุณแล้วและมันก็ทำตามที่คุณพูด แต่รหัสของฉันก็เป็นไปตามที่ฉันอธิบายไว้ข้างต้น ฉันจะทำการทดลองเพิ่มเติมและดูว่าฉันสามารถรวบรวมตัวอย่างง่ายๆของผลลัพธ์ที่คุณสามารถลองได้หรือไม่
Mnebuerquo

1
ตกลง. มันต้องเป็นสิ่งที่ฉันทำผิดไป ฉันมั่นใจในเวลาที่ฉันโพสต์คำถามของฉันว่ามันใช้งานได้ดี แต่เนื่องจากฉันลองตัวอย่างของคุณแล้วฉันไม่ทำงานอีกต่อไป ฉันจะกลับไปใช้ window.location เพื่อเปลี่ยนหน้าและไม่ลองแกล้งคลิก
Mnebuerquo

อันที่จริงแล้วการคลิก () ไม่ได้หมายถึงการสร้างคลิกปลอม แต่บางครั้งเราสามารถใช้เพื่อคลิกปุ่มหรือแบบฟอร์มด้วยการฉีดจาวาสคริปต์หรือเพื่อความสะดวกในขณะที่สร้างฮอตคีย์ชั่วคราวที่อยู่ด้านบนของฟังก์ชันจาวาสคริปต์ที่มีอยู่
Aero Wang

241

อีกทางเลือกหนึ่งคือใช้วานิลลาจาวาสคริปต์:

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

1
สิ่งนี้ไม่สามารถใช้งานได้ใน Safari และตามข้อกำหนด HTML เพียงอินพุตเท่านั้นที่ต้องใช้สิ่งนี้
Jeremy Kauffman

4
แดง! มันใช้งานได้! แต่ฉันต้องบอกว่ามันไม่ใช่จาวาสคริปต์ "วานิลลา" เนื่องจากใช้องค์ประกอบ jquery ดังนั้นจึงเป็นจาวาสคริปต์ jquery ประเภทของวานิลลา ... มันทำงานได้ใน Firefox 24 และ IE 10
bgmCoder

@BGM โอเค แต่การคลิก () ไม่ได้อยู่ในองค์ประกอบ jquery คุณสามารถแทนที่มันด้วย getElementById (".. "). คลิก ()
ปีเตอร์

ว้าวแผลเต็มทำงานได้ตามที่คาดไว้ +1 ที่ได้รับ :) สำหรับผู้ใช้รายอื่นคุณสามารถใช้เช่น: var lnk = document.getElementById ("a_link"); ถ้า (lnk == null) {// ทำบางอย่าง .... } else {lnk.click (); }
อิกบัล

ทดสอบในเบราว์เซอร์ต่าง ๆ IE10 & Jquery 1.6.4 ไม่สามารถจัดการกับสิ่งนี้ได้
Hannes Schneidermayer

65

หากคุณดูที่รหัสสำหรับ$.clickฟังก์ชั่นฉันจะเดิมพันจะมีคำสั่งแบบมีเงื่อนไขที่ตรวจสอบเพื่อดูว่าองค์ประกอบมีผู้ฟังที่ลงทะเบียนสำหรับclickเหตุการณ์ก่อนที่จะดำเนินการหรือไม่ ทำไมไม่เพียงแค่รับแอhrefททริบิวจากลิงค์และเปลี่ยนตำแหน่งของเพจด้วยตนเอง?

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

แก้ไข: นี่คือเหตุผลที่มันไม่คลิกผ่านจากtriggerแหล่ง jQuery สำหรับฟังก์ชัน 1.3.2:

 // 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ตัวจัดการดั้งเดิมถูกเรียก คุณจะต้องทำสิ่งที่ฉันทำและทำตามขั้นตอนเพื่อดูว่ามันถูกเรียกที่ไหน


แน่นอนฉันสามารถใช้ window.location และ href ตามที่ฉันกล่าวถึงในคำถาม ฉันพยายามเข้าใจว่าเกิดอะไรขึ้นใน jquery click () และสิ่งที่ทำให้เกิดผลลัพธ์ที่ฉันสังเกตเห็น
Mnebuerquo

ฉันแก้ไขคำตอบของฉันเพื่อแสดงว่าอยู่ที่ไหนในแหล่งที่มาของ jQuery ที่เกี่ยวข้องกับการโทร $ .click () บนลิงก์
34432 Ryan

2
window.location ทำงาน แต่ไม่โพสต์ผู้อ้างอิง HTTP และแบ่งปุ่มย้อนกลับ
Chase Seibert

5

คลิกตัวจัดการบนแท็กสมอเป็นกรณีพิเศษใน jQuery

ฉันคิดว่าคุณอาจสับสนระหว่างเหตุการณ์ onclick ของ anchor (รู้จักกันในเบราว์เซอร์) และ click event ของวัตถุ jQuery ซึ่งล้อมกรอบความคิดของ DOM ของแท็ก anchor

คุณสามารถดาวน์โหลดแหล่ง 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

JS / jQuery ไม่สนับสนุนพฤติกรรมเริ่มต้นของลิงก์ "คลิก" โดยทางโปรแกรม

สิ่งที่คุณสามารถทำได้คือสร้างแบบฟอร์มและส่ง วิธีนี้คุณไม่จำเป็นต้องใช้window.locationหรือwindow.openซึ่งเบราว์เซอร์มักถูกบล็อกว่าเป็นป๊อปอัปที่ไม่ต้องการ

สคริปต์นี้มี 2 วิธีที่แตกต่าง: หนึ่งที่พยายามเปิด 3 แท็บใหม่ / หน้าต่าง (เปิดเพียง 1 ใน IE และ Chrome, ข้อมูลเพิ่มเติมด้านล่าง) และหนึ่งที่ fires เหตุการณ์ที่กำหนดเองเมื่อคลิกลิงค์

นี่คือวิธี:

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;
    });

});

มันมีไว้สำหรับองค์ประกอบลิงก์แต่ละรายการ:

  1. สร้างแบบฟอร์ม
  2. ให้มันแอตทริบิวต์
  3. ผนวกเข้ากับ DOM เพื่อให้สามารถส่งได้
  4. ส่งมัน
  5. ลบแบบฟอร์มออกจาก DOM ลบร่องรอยทั้งหมด * ใส่ evil laugh *

ตอนนี้คุณมีการโหลดแท็บ / หน้าต่างใหม่"https://google.nl"(หรือ URL ใด ๆ ที่คุณต้องการเพียงแค่แทนที่) น่าเสียดายที่เมื่อคุณพยายามเปิดมากกว่าหนึ่งหน้าต่างด้วยวิธีนี้คุณจะได้รับPopup blockedแถบข้อความเมื่อพยายามเปิดหน้าต่างที่สอง (อันแรกยังคงเปิดอยู่)


ข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ฉันใช้วิธีนี้พบได้ที่นี่

เปิดหน้าต่าง / แท็บใหม่โดยไม่ใช้window.openหรือwindow.location.href


3

ทริกเกอร์องค์ประกอบเชื่อมโยงหลายมิติที่อยู่ภายในองค์ประกอบที่คุณต้องการเชื่อมต่อ jquery .click ()

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

ในสคริปต์ของคุณคุณเชื่อมต่อไปยังคอนเทนเนอร์หลักที่คุณต้องการคลิกเหตุการณ์ จากนั้นคุณใช้วิธีการ jquery มาตรฐานเพื่อค้นหาองค์ประกอบ (ประเภทคลาส id) และเริ่มการคลิก สิ่งที่เกิดขึ้นคือ jquery เข้าสู่ฟังก์ชั่นวนซ้ำเพื่อเริ่มการคลิกและคุณทำลายฟังก์ชั่นวนซ้ำโดยรับฟังก์ชั่น 'e' และ stopPropagation () และคืนค่าเท็จเพราะคุณไม่ต้องการให้ jQuery ทำอะไรอย่างอื่น

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

ทางเลือกอื่นคือห่อภาชนะในองค์ประกอบและวางเป็นภาชนะด้านในแทนที่จะเป็นภาชนะ ตั้งช่วงให้แสดงบล็อกเพื่อให้สอดคล้องกับมาตรฐาน w3c


3

คุณสามารถใช้ 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() });

2

ไม่ทำอะไรเลยเพราะไม่มีเหตุการณ์ผูกมัดกับเหตุการณ์ หากฉันจำได้อย่างถูกต้อง jQuery จะเก็บรักษารายการตัวจัดการเหตุการณ์ของตนเองที่เชื่อมโยงกับ NodeLists เพื่อประสิทธิภาพและวัตถุประสงค์อื่น ๆ


2

หากคุณต้องการคุณสมบัตินี้สำหรับกรณีหนึ่งหรือน้อยมาก (คุณเป็นทั้งแอปที่ไม่ต้องการคุณสมบัตินี้) ฉันอยากจะปล่อยให้ 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);
  })()

1

หากต้องการเปิดไฮเปอร์ลิงก์ในแท็บเดียวกันให้ใช้:

$(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;
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.