Як імітувати клацання миші за допомогою JavaScript?


137

Я знаю про document.form.button.click()метод. Однак я хотів би знати, як імітувати onclickподію.

Я знайшов цей код десь тут, на Stack Overflow, але не знаю, як ним користуватися :(

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

Як запустити подію клацання миші за допомогою JavaScript?


3
Чого ви намагаєтесь досягти, роблячи це?
Ерік

@Nok Imchen - Чи можете ви надати посилання на оригінальне запитання, від якого ви отримали код?
Джаред Фарріш

@Eric, це те саме, що наведено нижче посилання
Nok Imchen

@jared, ось посилання stackoverflow.com/questions/433919 / ...
Нок Imchen

Відповіді:


216

(Модифікована версія, щоб вона працювала без 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
}

Ви можете використовувати його так:

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

Зауважте, що в якості третього параметра ви можете передати "параметри". Параметри, які ви не вказуєте, взяті з defaultOptions (див. Нижню частину сценарію). Отже, якщо ви, наприклад, хочете вказати координати миші, ви можете зробити щось на кшталт:

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

Ви можете використовувати аналогічний підхід для зміни інших параметрів за замовчуванням.

Кредити повинні перейти до кенгаксу . Ось початкове джерело (специфічне для prototype.js).


6
Кредити мають перейти до кенгаксу, як зазначено у моїй відповіді. Я зробив це в бібліотеці агностиком :)
TweeZz

Як передати координати миші до цього сценарію?
Дмитро

1
Я відредагую публікацію і додаю приклад того, як можна було пройти в координатах миші ..
TweeZz

1
Я перетворив це на модуль CoffeeScript для легкого включення у ваші проекти тут: github.com/joscha/eventr
Joscha

1
чим це відрізняється від $ (el) .click (), оскільки ваше рішення працює для мене, варіант jquery не працює
Silver Ringvee

53

Ось чиста функція JavaScript, яка буде імітувати клацання (або будь-яку подію миші) на цільовому елементі:

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

Ось робочий приклад: http://www.spookandpuff.com/examples/clickSimulation.html

Ви можете імітувати клацання на будь-якому елементі DOM . Щось подібне simulatedClick(document.getElementById('yourButtonId'))спрацювало б.

Ви можете передати об'єкт в optionsпереопрацювання за замовчуванням (для імітації того, яку кнопку миші ви хочете, Shift/ Alt/ Ctrlтримається тощо). Параметри, які вона приймає, базуються на API MouseEvents .

Я тестував Firefox, Safari та Chrome. Internet Explorer може знадобитися спеціальне лікування, я не впевнений.


Це було чудово для мене в Chrome, де елементи, схоже, не мають події click ().
Корабель Говард М. Льюїс

Це чудово - хіба, type: options.click || 'click'мабуть, має бути type: options.type || 'click'.
Елліот Вінклер

Проблема цього рішення полягає в тому, що він не буде клацати елементи, що містять вміст. напр. <div id = "outer"><div id = "inner"></div></div> simulatedClick(document.getElementById('outer'));не натисне внутрішній елемент.
dwjohnston

1
Це не так, як працює бульбашка подій - якщо натиснути на зовнішній елемент, його предки отримують подію клацання, коли вона пухирчить, але діти її не роблять. Уявіть, якби у вашій зовнішній divмістилася кнопка чи посилання - ви не хочете, щоб натискання на зовнішнє викликало натискання на внутрішній елемент.
Бен Халл

5
Не використовуйте ||оператора для подібних випадків, тому що whoops canBubble:options.canBubble || true,завжди оцінює істинне зараз, і, мабуть, ніхто його не помітить протягом 5 років.
Вінчестро

51

Більш простим і стандартним способом імітувати клацання миші буде безпосередньо за допомогою конструктора подій створити подію та відправити її.

Хоча MouseEvent.initMouseEvent()метод зберігається для зворотної сумісності, створення об'єкта MouseEvent слід робити за допомогою MouseEvent()конструктора.

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

Демо: http://jsfiddle.net/DerekL/932wyok6/

Це працює на всіх сучасних браузерах. На MouseEvent.initMouseEventжаль, для старих веб-переглядачів, включаючи IE, доведеться використовувати, на жаль, застарілі.

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

Це здається невдалим, коли елемент A, на який я хочу натиснути, має href = "javascript: void (0)", і він відповідає на інший обробник кліків, який був приєднаний до об'єкта.
deejbee

чи є швидкий спосіб отримати спільні події? Я помічаю, що я можу легко натиснути кнопку, але чи немає стандартного evt "mouseenter", "mouseleave", на який я можу просто посилатись, а не створювати новий mouseevent, як це зроблено вище?
вулиця Джеймса Джошуа

12

З документації на Мережу розробників Mozilla (MDN) HTMLElement.click () - це те, що ви шукаєте. Ви можете дізнатися більше подій тут .


2
@Ercksen Як йдеться на сторінці MDN, він запускає подія клацання елемента лише при використанні з елементами, які його підтримують (наприклад, один із типів <input>).
Крістоф

9

Спираючись на відповідь Дерека, я це підтвердив

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

працює, як очікувалося, навіть із ключовими модифікаторами. І це не є застарілим API, наскільки я бачу. Ви також можете підтвердити цю сторінку .



-1

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

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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.