Как симулировать щелчок мышью с помощью 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

Ответы:


217

(Измененная версия, чтобы она работала без 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

54

Вот функция 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
Однако это не то, как работает всплывающее сообщение о событии - если вы щелкнете по внешнему элементу, его предки получат событие click, когда оно всплывет, а его потомки - нет. Представьте, что ваш внешний divэлемент содержит кнопку или ссылку - вы не хотите, чтобы щелчок по внешнему элементу вызывал щелчок по внутреннему элементу.
Бен Халл

5
Не используйте ||оператор в таких случаях, потому что к сожалению, canBubble:options.canBubble || true,теперь всегда имеет значение 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/

Это работает во всех современных браузерах. Для старых браузеров, включая IE, MouseEvent.initMouseEventпридется использовать, к сожалению, хотя это не рекомендуется.

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)", и он отвечает на другой обработчик кликов, который был прикреплен к объекту.
Диджби

Есть ли быстрый способ получить общие события? Я заметил, что могу легко нажимать кнопку на кнопке, но нет ли стандартного «mouseenter», «mouseleave» evt, на который я могу просто ссылаться, а не создавать новое событие mousee, как было сделано выше?
Улица Джеймса Джошуа

12

Из документации Mozilla Developer Network (MDN) HTMLElement.click () - это то, что вы ищете. Вы можете узнать больше событий здесь .


2
@Ercksen Как говорит страница MDN, она запускает событие click элемента только при использовании с элементами, которые его поддерживают (например, одним из типов <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.