PhantomJS; bir öğeyi tıklayın


81

PhantomJS'de bir öğeyi nasıl tıklatırım?

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

Bu bana "tanımsız bir işlev değil ..." hatası veriyor.

Yerine ben

 return document.getElementById('idButtonSpan');

ve sonra yazdırın,

daha sonra [nesne nesnesini] yazdırır, böylece öğe var olur.

Öğe bir düğme görevi görür, ancak aslında yalnızca bir yayılma öğesi, gönderme girişi değil.

Casper ile çalışmak için bu düğmeyi tıklamayı başardım, ancak Casper'ın başka sınırlamaları vardı, bu yüzden PhantomJS'ye geri döndüm.


28
Cevabı kabul etme zamanı.

"DispatchEvent" işlevini kullanan 3 yanıt vardır, bunlardan 2'si "sendEvent" i kullanır, biri pratikte yararsızdır ve biri yorum olmalıdır.
redbeam_


Neden hiç kimse bunun click()DOM API'de bulunmadığına işaret etmedi, muhtemelen jQuery'de veya bunun gibi bir kitaplıkta görmüşsünüzdür?
YemSalat

4 yıl sonra: Cevap kabul edildi! PhantomJS'den uzaklaştım, bu yüzden cevabı doğrulayamadım. Ancak 58 olumlu oylamanın doğru olduğunu kabul edeceğim :) @torazaburo
user984003

Yanıtlar:


68

.click()standart değil. Bir olay oluşturmanız ve onu göndermeniz gerekir:

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

9
elJQuery ile sarma size bu tıklama tanımını verir. Tarayıcınızda ve Phantom'da çalışacaktır. $(el).click()
Bluu

3
Aman Tanrım, bununla neredeyse 12 saat sürekli mücadelenin ardından neşe gözyaşları! kokla kokla!
user1323136

1
Benim için de iyi çalıştı, ancak işlem bitmeden PhantomJS'den çok erken çıkılmaması gerektiğini hatırlamak gerekiyor. Sadece bir düğmeyi tıklayıp çıkmak için kısa bir komut dosyasına ihtiyacım vardı. Page.onLoadFinished = function () {...} içinden phantom.exit () 'i çağırana kadar bu benim için işe yaramayacaktı;
gregko

document.querySelector (element) .click () benim için gayet iyi çalışıyor.
GracefulCode

Özel kontrollerle çalışmak için 3 olay ile daha karmaşık bir çözüm yapmam gerekiyordu: function triggerMouseEvent (elm, eventType) {var ev = document.createEvent ("MouseEvent"); ev.initMouseEvent (eventType, true / * bubble /, true / cancelable /, window, null, 0, 0, 0, 0, / koordinates / false, false, false, false, / değiştirici tuşları * / 0 / * sol * /, boş ); elm.dispatchEvent (ev); } function click (elm) {triggerMouseEvent (elm, 'mousedown'); triggerMouseEvent (karaağaç, 'mouseup'); triggerMouseEvent (karaağaç, 'tıklama'); }
a-bobkov

34

@ Torazaburo'nun yanıtına alternatif olarak PhantomJS'de HTMLElement.prototype.clickçalışırken stub yapabilirsiniz. Örneğin, testlerimizi çalıştırmak için PhantomJS + QUnit kullanıyoruz ve bizim içinde qunit-config.jsşöyle bir şey var:

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

1
PhantomJs 1.9.7-14 ile Karma 0.12.17 çalıştırdığıma dair bir uyarı. window._phantomNesne yok, bu yüzden sadece bu koşulu kaldırdım ve beklendiği gibi çalıştı.
BradGreens

MouseEvent için farklı koordinatlar ayarlamak için fonksiyonun parametreleri kabul edip etmemesi gerektiğini merak ediyorum
ffflabs

16

Güzel değil, ancak seçim için jQuery kullanmama izin vermek için bunu kullanıyorum:

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

ancak her zaman yerini alabilir $(s)[0]ile document.querySelector(s)jQuery kullanarak değilse.

(Bu, öğenin göz önünde bulundurulmasına bağlıdır, yani viewportSize.height yeterince büyüktür).


2
Tüm olası yaklaşımları denedim ve tıklamaya çalışırken benim için çalışan tek seçenek bu tr.
Kai

Phantomjs 1.9.0 üzerinde ve bir <a> elemanıyla çalıştı
redbeam_

1
en iyi çözüm imo,+1
Flash Thunder

10

Aşağıdaki yöntemin yararlı olacağını umuyoruz. 1.9 sürümünde benim için çalıştı

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

Bu benim için çalıştı. Umarım bu başkaları için de yararlı olur


@Jobins john whats waitforload = doğru?
Kadir Hüseyin

1
@QadirHussain Aslında sayfanın tamamen yüklenmesini bekliyor. Neredeyse sayfayı yüklemek için belirli bir zaman ayarlamak gibi.
Jobins John

6

İle 1.9.2bu benim için çalıştı, tıklama işleyicileri tetiklenen:

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

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

Tüm unsurlarda değil. Örneğin <a> buna sahip değil. Düğmelerde orada.
2014

6

evaluatebunun gibi basit bir JavaScript kullanın :

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

1
Aslında şimdi PhantomJS 2.x ile artık doğru çözüm IS
BlaM

3

Öğeyi hiçbir zaman doğrudan tıklayamadım. Bunun yerine, onclick ile hangi fonksiyonun çağrıldığını bulmak için html'ye baktım ve sonra o fonksiyonu çağırdım.


işlevi nasıl bulabilir ve addEventListener aracılığıyla eklenmişse nasıl çağırırsınız?
Suo6613

2

Document.querySelector (element) .click () Phantomjs 2.0 kullanılırken çalışır

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

PhantomJS ile çift tıklama da mümkündür.

Önerilen

Bu uyarlanmıştır yanıt arasında stovroz ve yerli tetikler dblclickiçerenmousedown , mouseupve clicketkinlikleri (her ikisi).

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

Diğer yollar

Aşağıdaki iki yol yalnızca dblclickolayı tetikler , ancak ondan önce gelmesi gereken diğer olayları tetiklemez .

Dan uyarlanan bu cevabı ait 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);

Dan uyarlanan bu cevabın ait 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);

Tam test komut dosyası


2

En kolay yol jQuery kullanmaktır.

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

0

JQuery kullananlar için, JQuery UI bunları simüle etmek için bir yardımcı program oluşturdu: jquery-simulate . Bunu PhantomJS ve Chrome'da kullanıyorum

$ele..simulate( "click" );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.