Bagaimana cara mensimulasikan klik mouse menggunakan JavaScript?

140

Saya tahu tentang document.form.button.click()metodenya. Namun, saya ingin tahu bagaimana mensimulasikan onclickacara tersebut.

Saya menemukan kode ini di suatu tempat di Stack Overflow, tetapi saya tidak tahu cara menggunakannya :(

function contextMenuClick()
{
    var element= 'button'

    var evt = element.ownerDocument.createEvent('MouseEvents');

    evt.initMouseEvent('contextmenu', true, true,
         element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false,
         false, false, false, 1, null);

    element.dispatchEvent(evt);
}

Bagaimana cara mengaktifkan peristiwa klik mouse menggunakan JavaScript?

Nok Imchen
sumber
3
Apa yang ingin Anda capai dengan melakukan itu?
Eric
@Nok Imchen - Dapatkah Anda memberikan tautan ke pertanyaan awal kode asal Anda?
Jared Farrish
@ Eric, itu sama dengan tautan yang diberikan di bawah ini
Nok Imchen
@jared, ini tautan stackoverflow.com/questions/433919/…
Nok Imchen

Jawaban:

218

(Versi modifikasi untuk membuatnya berfungsi tanpa prototype.js)

function simulate(element, eventName)
{
    var options = extend(defaultOptions, arguments[2] || {});
    var oEvent, eventType = null;

    for (var name in eventMatchers)
    {
        if (eventMatchers[name].test(eventName)) { eventType = name; break; }
    }

    if (!eventType)
        throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');

    if (document.createEvent)
    {
        oEvent = document.createEvent(eventType);
        if (eventType == 'HTMLEvents')
        {
            oEvent.initEvent(eventName, options.bubbles, options.cancelable);
        }
        else
        {
            oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
            options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
            options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
        }
        element.dispatchEvent(oEvent);
    }
    else
    {
        options.clientX = options.pointerX;
        options.clientY = options.pointerY;
        var evt = document.createEventObject();
        oEvent = extend(evt, options);
        element.fireEvent('on' + eventName, oEvent);
    }
    return element;
}

function extend(destination, source) {
    for (var property in source)
      destination[property] = source[property];
    return destination;
}

var eventMatchers = {
    'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
    'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/
}
var defaultOptions = {
    pointerX: 0,
    pointerY: 0,
    button: 0,
    ctrlKey: false,
    altKey: false,
    shiftKey: false,
    metaKey: false,
    bubbles: true,
    cancelable: true
}

Anda bisa menggunakannya seperti ini:

simulate(document.getElementById("btn"), "click");

Perhatikan bahwa sebagai parameter ketiga, Anda dapat memasukkan 'opsi'. Opsi yang tidak Anda tentukan diambil dari defaultOptions (lihat bagian bawah skrip). Jadi, jika Anda misalnya ingin menentukan koordinat mouse, Anda dapat melakukan sesuatu seperti:

simulate(document.getElementById("btn"), "click", { pointerX: 123, pointerY: 321 })

Anda dapat menggunakan pendekatan serupa untuk mengganti opsi default lainnya.

Kredit harus diberikan kepada kangax . Berikut adalah sumber aslinya (spesifik prototype.js).

TweeZz
sumber
6
Kredit harus diberikan ke kangax, seperti yang tercantum dalam jawaban saya. Saya membuatnya menjadi perpustakaan agnostik :)
TweeZz
Bagaimana cara meneruskan koordinat mouse ke skrip ini?
Dmitry
1
Saya akan mengedit posting dan menambahkan contoh bagaimana Anda dapat mengirimkan koordinat mouse ..
TweeZz
1
Saya mengubahnya menjadi modul CoffeeScript agar mudah dimasukkan dalam proyek Anda di sini: github.com/joscha/eventr
Joscha
1
bagaimana ini berbeda dari $ (el) .click (), karena solusi Anda berfungsi untuk saya, opsi jquery tidak
Silver Ringvee
55

Berikut adalah fungsi JavaScript murni yang akan mensimulasikan klik (atau peristiwa mouse apa pun) pada elemen target:

function simulatedClick(target, options) {

  var event = target.ownerDocument.createEvent('MouseEvents'),
      options = options || {},
      opts = { // These are the default values, set up for un-modified left clicks
        type: 'click',
        canBubble: true,
        cancelable: true,
        view: target.ownerDocument.defaultView,
        detail: 1,
        screenX: 0, //The coordinates within the entire page
        screenY: 0,
        clientX: 0, //The coordinates within the viewport
        clientY: 0,
        ctrlKey: false,
        altKey: false,
        shiftKey: false,
        metaKey: false, //I *think* 'meta' is 'Cmd/Apple' on Mac, and 'Windows key' on Win. Not sure, though!
        button: 0, //0 = left, 1 = middle, 2 = right
        relatedTarget: null,
      };

  //Merge the options with the defaults
  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      opts[key] = options[key];
    }
  }

  //Pass in the options
  event.initMouseEvent(
      opts.type,
      opts.canBubble,
      opts.cancelable,
      opts.view,
      opts.detail,
      opts.screenX,
      opts.screenY,
      opts.clientX,
      opts.clientY,
      opts.ctrlKey,
      opts.altKey,
      opts.shiftKey,
      opts.metaKey,
      opts.button,
      opts.relatedTarget
  );

  //Fire the event
  target.dispatchEvent(event);
}

Berikut adalah contoh yang berfungsi: http://www.spookandpuff.com/examples/clickSimulation.html

Anda dapat menyimulasikan klik pada elemen apa pun di DOM . Sesuatu seperti itu simulatedClick(document.getElementById('yourButtonId'))akan berhasil.

Anda dapat mengirimkan sebuah objek ke optionsuntuk menimpa default (untuk mensimulasikan tombol mouse mana yang Anda inginkan, apakah Shift/ Alt/ Ctrlditahan, dll. Opsi yang diterimanya didasarkan pada MouseEvents API .

Saya telah menguji di Firefox, Safari, dan Chrome. Internet Explorer mungkin memerlukan perlakuan khusus, saya tidak yakin.

Ben Hull
sumber
Ini berfungsi dengan baik bagi saya, di Chrome, di mana elemennya tampaknya tidak memiliki peristiwa click ().
Kapal Howard M. Lewis
Ini bagus - kecuali type: options.click || 'click'mungkin seharusnya begitu type: options.type || 'click'.
Elliot Winkler
Masalah dengan solusi ini adalah tidak akan mengklik elemen yang terkandung. misalnya. <div id = "outer"><div id = "inner"></div></div> simulatedClick(document.getElementById('outer'));tidak akan mengklik elemen dalam.
dwjohnston
1
Itu bukan cara kerja peristiwa menggelembung - jika Anda mengklik elemen luar, leluhurnya menerima peristiwa klik saat menggelembung, tetapi anak-anaknya tidak. Bayangkan jika bagian luar Anda divberisi tombol atau tautan - Anda tidak ingin klik di bagian luar memicu klik pada elemen dalam.
Ben Hull
5
Jangan gunakan ||operator untuk kasus seperti ini, karena ups, canBubble:options.canBubble || true,selalu nilai true sekarang, dan sepertinya tidak akan ada yang menyadarinya selama 5 tahun.
Winchestro
54

Cara yang lebih mudah dan lebih standar untuk mensimulasikan klik mouse adalah secara langsung menggunakan konstruktor acara untuk membuat acara dan mengirimkannya.

Meskipun MouseEvent.initMouseEvent()metode ini disimpan untuk kompatibilitas ke belakang, pembuatan objek MouseEvent harus dilakukan menggunakan MouseEvent()konstruktor.

var evt = new MouseEvent("click", {
    view: window,
    bubbles: true,
    cancelable: true,
    clientX: 20,
    /* whatever properties you want to give it */
});
targetElement.dispatchEvent(evt);

Demo: http://jsfiddle.net/DerekL/932wyok6/

Ini berfungsi di semua browser modern. Untuk browser lama termasuk IE, MouseEvent.initMouseEventsayangnya harus digunakan meskipun sudah usang.

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", canBubble, cancelable, view,
                   detail, screenX, screenY, clientX, clientY,
                   ctrlKey, altKey, shiftKey, metaKey,
                   button, relatedTarget);
targetElement.dispatchEvent(evt);
Derek 朕 會 功夫
sumber
Tampaknya ini gagal ketika elemen A yang ingin saya klik memiliki href = "javascript: void (0)" dan merespons handler klik lain yang telah dilampirkan ke objek.
deejbee
adakah cara cepat untuk mendapatkan acara umum? Saya perhatikan saya dapat meningkatkan klik dengan mudah pada sebuah tombol, tetapi apakah tidak ada "mouseenter" standar, "mouseleave" evt yang dapat saya referensikan daripada membuat acara mouse baru seperti yang dilakukan di atas?
James Joshua Street
12

Dari dokumentasi Mozilla Developer Network (MDN), HTMLElement.click () adalah yang Anda cari. Anda dapat mengetahui lebih banyak acara di sini .

Lewis
sumber
2
@Ercksen Seperti yang dikatakan oleh halaman MDN, ini hanya mengaktifkan event klik elemen ketika digunakan dengan elemen yang mendukungnya (misalnya salah satu tipe <input>).
Christophe
10

Berdasarkan jawaban Derek, saya memverifikasi itu

document.getElementById('testTarget')
  .dispatchEvent(new MouseEvent('click', {shiftKey: true}))

berfungsi seperti yang diharapkan bahkan dengan pengubah kunci. Dan ini bukan API yang usang, sejauh yang saya bisa lihat. Anda juga dapat memverifikasi di halaman ini .

Wizek
sumber
-1

Kode JavaScript

   //this function is used to fire click event
    function eventFire(el, etype){
      if (el.fireEvent) {
        el.fireEvent('on' + etype);
      } else {
        var evObj = document.createEvent('Events');
        evObj.initEvent(etype, true, false);
        el.dispatchEvent(evObj);
      }
    }

function showPdf(){
  eventFire(document.getElementById('picToClick'), 'click');
}

Kode HTML

<img id="picToClick" data-toggle="modal" data-target="#pdfModal" src="img/Adobe-icon.png" ng-hide="1===1">
  <button onclick="showPdf()">Click me</button>
BERGUIGA Mohamed Amine
sumber