web-dev-qa-db-de.com

PhantomJS; Klicken Sie auf ein Element

Wie klicke ich auf ein Element in PhantomJS?

page.evaluate(function() {
    document.getElementById('idButtonSpan').click();  
});

Dies gibt mir einen Fehler "undefined ist keine Funktion ..."

Wenn ich stattdessen 

 return document.getElementById('idButtonSpan');

und dann drucken,

dann wird [object object] gedruckt, sodass das Element vorhanden ist.

Das Element fungiert als Schaltfläche, ist aber eigentlich nur ein Span-Element und keine Eingabe-Eingabe.

Ich konnte diesen Button per Klick bekommen, um mit Casper zu arbeiten, aber Casper hatte andere Einschränkungen, also bin ich wieder bei PhantomJS.

79
user984003

.click() ist kein Standard. Sie müssen ein Ereignis erstellen und absenden:

function click(el){
    var ev = document.createEvent("MouseEvent");
    ev.initMouseEvent(
        "click",
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null
    );
    el.dispatchEvent(ev);
}
65
user663031

Alternativ zur @ torazaburo-Antwort können Sie HTMLElement.prototype.click in PhantomJS stubben. Zum Beispiel verwenden wir PhantomJS + QUnit, um unsere Tests auszuführen, und in unserem qunit-config.js haben wir so etwas wie:

if (window._phantom) {
  // Patch since PhantomJS does not implement click() on HTMLElement. In some 
  // cases we need to execute the native click on an element. However, jQuery's 
  // $.fn.click() does not dispatch to the native function on <a> elements, so we
  // can't use it in our implementations: $el[0].click() to correctly dispatch.
  if (!HTMLElement.prototype.click) {
    HTMLElement.prototype.click = function() {
      var ev = document.createEvent('MouseEvent');
      ev.initMouseEvent(
          'click',
          /*bubble*/true, /*cancelable*/true,
          window, null,
          0, 0, 0, 0, /*coordinates*/
          false, false, false, false, /*modifier keys*/
          0/*button=left*/, null
      );
      this.dispatchEvent(ev);
    };
  }
}
34
TheCloudlessSky

Es ist nicht hübsch, aber ich habe dies verwendet, um jQuery für die Auswahl zu verwenden:

var rect = page.evaluate(function() {
    return $('a.whatever')[0].getBoundingClientRect();
});
page.sendEvent('click', rect.left + rect.width / 2, rect.top + rect.height / 2);

sie können jedoch $(s)[0] immer durch document.querySelector(s) ersetzen, wenn Sie jQuery nicht verwenden.

(Es ist darauf angewiesen, dass das Element im Blickfeld ist, d. H. Ihre viewportSize.height ist groß genug).

15
stovroz

Hoffe, dass die folgende Methode nützlich sein wird. In Version 1.9 hat es für mich funktioniert

page.evaluate(function(){
    var a = document.getElementById("spr-sign-in-btn-standard");
    var e = document.createEvent('MouseEvents');
    e.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    a.dispatchEvent(e);
    waitforload = true;
});

Das hat bei mir funktioniert. Ich hoffe, dass dies auch für andere nützlich sein wird

9
Jobins John

verwenden Sie einfaches JavaScript mit evaluate, etwa so:

page.evaluate(function() {
    document.getElementById('yourId').click();
});
6
HappyCoder888

Mit 1.9.2, das für mich funktioniert hat, wurden Click-Handler ausgelöst: 

var a = page.evaluate(function() {
    return document.querySelector('a.open');
});

page.sendEvent('click', a.offsetLeft, a.offsetTop);
6
sshaw

Der einfachste Weg ist die Verwendung von jQuery.

page.evaluate(function() {
  page.includeJs("your_jquery_file.js", function() {
    page.evaluate(function() {
      $('button[data-control-name="see_more"]').click();
    });
  });
});
2
Forrest Chang

Doppelklicks sind auch mit PhantomJS möglich.

Empfohlen

Dies wird von der Antwort von stovroz angepasst und löst eine native dblclick aus, die die mousedown-, mouseup- und click-Ereignisse (jeweils zwei) enthält.

var rect = page.evaluate(function(selector){
    return document.querySelector(selector).getBoundingClientRect();
}, selector);
page.sendEvent('doubleclick', rect.left + rect.width / 2, rect.top + rect.height / 2);

Andere Möglichkeiten

Die folgenden zwei Möglichkeiten lösen nur das dblclick-Ereignis aus, nicht jedoch die anderen Ereignisse, die dem Ereignis vorausgehen sollen.

Angepasst von dieser Antwort von torazaburo :

page.evaluate(function(selector){
    var el = document.querySelector(sel);
    var ev = document.createEvent("MouseEvent");
    ev.initMouseEvent(
        'dblclick',
        true /* bubble */, true /* cancelable */,
        window, null,
        0, 0, 0, 0, /* coordinates */
        false, false, false, false, /* modifier keys */
        0 /*left*/, null
    );
    el.dispatchEvent(ev);
}, selector);

Angepasst von dieser Antwort von Jobins John :

page.evaluate(function(selector){
    var el = document.querySelector(sel);
    var e = document.createEvent('MouseEvents');
    e.initMouseEvent('dblclick', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    el.dispatchEvent(e);
}, selector);

Vollständiges Testskript

2
Artjom B.

Ich konnte das Element nie direkt anklicken. Stattdessen habe ich mir die HTML-Datei angesehen, um herauszufinden, welche Funktion mit onclick aufgerufen wurde. 

2
user984003

Document.querySelector (Element) .click () funktioniert bei Verwendung von Phantomjs 2.0

click: function (selector, options, callback) {
    var self = this;
    var deferred = Q.defer();
    options = options || {timeout:1000}; 
    setTimeout(function () { 
        self.page.evaluate(function(targetSelector) {
            $(document).ready(function() {
                document.querySelector(targetSelector).click();
            }) ;
        }, function () {
                deferred.resolve();
        }, selector);
    }, options.timeout);
    return deferred.promise.nodeify(callback);
},
2
GracefulCode

Für Benutzer, die JQuery verwenden, hat die JQuery-Benutzeroberfläche ein Dienstprogramm erstellt, um diese zu simulieren: jquery-simulate Ich verwende dies in PhantomJS und Chrome

$ele..simulate( "click" );
0
wbdarby