Jak symulować kliknięcie myszą za pomocą JavaScript?

137

Wiem o document.form.button.click()metodzie. Chciałbym jednak wiedzieć, jak zasymulować to onclickwydarzenie.

Znalazłem ten kod gdzieś tutaj w Stack Overflow, ale nie wiem, jak go użyć :(

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

Jak uruchomić zdarzenie kliknięcia myszą za pomocą JavaScript?

Nok Imchen
źródło
3
Co starasz się przez to osiągnąć?
Eric
@Nok Imchen - Czy możesz podać link do oryginalnego pytania, z którego otrzymałeś kod?
Jared Farrish
@Eric, to to samo, co link podany poniżej
Nok Imchen
@jared, oto link stackoverflow.com/questions/433919/…
Nok Imchen

Odpowiedzi:

216

(Zmodyfikowana wersja, aby działała bez 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
}

Możesz go używać w ten sposób:

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

Zauważ, że jako trzeci parametr możesz podać „opcje”. Opcje, których nie określisz, są pobierane z defaultOptions (patrz dolna część skryptu). Więc jeśli na przykład chcesz określić współrzędne myszy, możesz zrobić coś takiego:

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

Możesz użyć podobnego podejścia, aby zastąpić inne opcje domyślne.

Kredyty powinny trafić do kangaxa . Oto oryginalne źródło (specyficzne dla prototype.js).

TweeZz
źródło
6
Kredyty powinny trafić do kangax, jak napisałem w mojej odpowiedzi. Zrobiłem to agnostyk biblioteki :)
TweeZz
Jak przekazać współrzędne myszy do tego skryptu?
Dmitry
1
Zredaguję
1
Przekształciłem to w moduł CoffeeScript, aby łatwo włączyć go do twoich projektów tutaj: github.com/joscha/eventr
Joscha
1
czym różni się to od $ (el) .click (), ponieważ twoje rozwiązanie działa dla mnie, opcja jquery nie
Silver Ringvee
53

Oto czysta funkcja JavaScript, która symuluje kliknięcie (lub dowolne zdarzenie myszy) na elemencie docelowym:

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

Oto działający przykład: http://www.spookandpuff.com/examples/clickSimulation.html

Możesz zasymulować kliknięcie dowolnego elementu w DOM . Coś takiego simulatedClick(document.getElementById('yourButtonId'))mogłoby zadziałać.

Możesz przekazać obiekt do, optionsaby nadpisać ustawienia domyślne (aby zasymulować wybrany przycisk myszy, czy Shift/ Alt/ Ctrlsą przytrzymane itp. Opcje, które akceptuje, są oparte na API MouseEvents .

Testowałem w Firefoksie, Safari i Chrome. Internet Explorer może wymagać specjalnego traktowania, nie jestem pewien.

Ben Hull
źródło
To działało świetnie dla mnie, w Chrome, gdzie elementy wydają się nie mieć zdarzenia click ().
Howard M. Lewis Ship
To jest świetne - chyba że type: options.click || 'click'powinno być type: options.type || 'click'.
Elliot Winkler
Problem z tym rozwiązaniem polega na tym, że nie kliknie zawartych elementów. na przykład. <div id = "outer"><div id = "inner"></div></div> simulatedClick(document.getElementById('outer'));nie kliknie elementu wewnętrznego.
dwjohnston,
1
Jednak nie tak działa propagacja zdarzeń - jeśli klikniesz element zewnętrzny, to jego przodkowie otrzymają zdarzenie kliknięcia, gdy się ono rozwija, ale jego elementy podrzędne nie. Wyobraź sobie, że zewnętrzna strona divzawiera przycisk lub łącze - nie chciałbyś, aby kliknięcie zewnętrznej strony powodowało kliknięcie wewnętrznego elementu.
Ben Hull
5
Nie używaj ||operatora w takich przypadkach, ponieważ ups, teraz canBubble:options.canBubble || true,zawsze zwraca wartość true i najwyraźniej nikt tego nie zauważy przez 5 lat.
Winchestro
51

Łatwiejszym i bardziej standardowym sposobem symulacji kliknięcia myszą byłoby bezpośrednie użycie konstruktora zdarzeń do utworzenia zdarzenia i wysłania go.

Chociaż MouseEvent.initMouseEvent()metoda jest zachowana w celu zapewnienia zgodności z poprzednimi wersjami, tworzenie obiektu MouseEvent powinno odbywać się przy użyciu MouseEvent()konstruktora.

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

Próbny: http://jsfiddle.net/DerekL/932wyok6/

Działa to we wszystkich nowoczesnych przeglądarkach. W przypadku starszych przeglądarek, w tym IE, MouseEvent.initMouseEventbędzie musiał być niestety używany, chociaż jest przestarzały.

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 朕 會 功夫
źródło
Wydaje się, że kończy się to niepowodzeniem, gdy element A, który chcę kliknąć, ma href = "javascript: void (0)" i odpowiada na inny moduł obsługi kliknięcia, który został dołączony do obiektu.
deejbee
czy istnieje szybki sposób na uzyskanie typowych wydarzeń? Zauważyłem, że mogę łatwo zwiększyć liczbę kliknięć na przycisku, ale czy nie ma standardowego „klawisza myszy”, „mouseleave”, do którego mogę się po prostu odwołać, zamiast tworzyć nowe wydarzenie dla myszy, jak powyżej?
James Joshua Street
12

Z dokumentacji Mozilla Developer Network (MDN), HTMLElement.click () jest tym, czego szukasz. Więcej informacji o wydarzeniach znajdziesz tutaj .

Chwytak
źródło
2
@Ercksen Jak mówi strona MDN, wywołuje zdarzenie click elementu tylko wtedy, gdy jest używany z elementami, które go obsługują (np. Jeden z typów <input>).
Christophe
9

W oparciu o odpowiedź Dereka, zweryfikowałem to

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

działa zgodnie z oczekiwaniami, nawet z kluczowymi modyfikatorami. O ile wiem, nie jest to przestarzały interfejs API. Możesz również zweryfikować na tej stronie .

Wizek
źródło
-1

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

Kod 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
źródło