PhantomJS; 要素をクリックします


81

PhantomJSで要素をクリックするにはどうすればよいですか?

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

これにより、「未定義は関数ではありません...」というエラーが表示されます。

代わりに私が

 return document.getElementById('idButtonSpan');

それを印刷して、

次に、[オブジェクトオブジェクト]を出力するため、要素は存在します。

この要素はボタンとして機能しますが、実際には単なるスパン要素であり、送信入力ではありません。

このボタンをクリックしてCasperを操作することはできましたが、Casperには他の制限があったため、PhantomJSに戻りました。


28
答えを受け入れる時間です。

「dispatchEvent」関数を使用する3つの回答、「sendEvent」を使用する2つ、実際には役に立たないもの、コメントである必要があるものがあります。
redbeam_ 2015年

#記号...忘れてはいけない
GracefulCode

click()DOM APIにまったく存在しないことをまだ誰も指摘していないのはなぜですか?おそらくjQueryまたはそのようなライブラリで見たのでしょうか?
YemSalat 2016

4年後:回答を受け付けました!PhantomJSから離れたので、答えを確認できませんでした。しかし、私は58の賛成票が正しいことを受け入れます:) @torazaburo
user984003

回答:


68

.click()標準ではありません。イベントを作成してディスパッチする必要があります。

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でラッピングすると、このクリックの定義が得られます。それはあなたのブラウザとファントムで動作します。$(el).click()
Bluu 2013年

3
これとのほぼ12時間の継続的な闘争の後、喜びの涙!スニフスニフ!
user1323136 2015年

1
私にとっても問題なく動作しましたが、処理が完了する前に、PhantomJSをすぐに終了しないように注意する必要があります。ボタンを1つクリックして終了するための短いスクリプトが必要でした。page.onLoadFinished = function(){...};内からphantom.exit()を呼び出すまで、これは機能しません。
gregko 2015年

document.querySelector(element).click()は私にとっては問題なく機能します。
gracefulCode 2016年

カスタムコントロールを操作するには、次の3つのイベントを使用してより複雑なソリューションを作成する必要がありました。functiontriggerMouseEvent(elm、eventType){var ev = document.createEvent( "MouseEvent"); ev.initMouseEvent(eventType、true / *バブル/、true /キャンセル可能/、ウィンドウ、null、 0、0、0、0 、/座標/ false、false、false、false、/修飾子キー* / 0 / *左* /、 ヌル ); elm.dispatchEvent(ev); } function click(elm){triggerMouseEvent(elm、 'mousedown'); triggerMouseEvent(elm、 'mouseup'); triggerMouseEvent(elm、 'クリック'); }
a-bobkov 2016年

34

@torazaburoの応答の代わりにHTMLElement.prototype.click、PhantomJSで実行しているときにスタブすることもできます。たとえば、PhantomJS + QUnitを使用してテストを実行すると、qunit-config.js次のようになります。

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
PhantomJs1.9.7-14でKarma0.12.17を実行していることに注意してください。window._phantomオブジェクトがないので、その条件を削除したところ、期待どおりに機能しました。
BradGreens 2014

MouseEventに異なる座標を設定するために、関数がパラメーターを受け入れる必要があるかどうか疑問に思います
ffflabs 2017

16

きれいではありませんが、これを使用して、選択にjQueryを使用できるようにしています。

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

しかし、あなたは常に置き換えることができる$(s)[0]document.querySelector(s)のjQueryを使用していない場合。

(これは、ビューマインドにある要素に依存します。つまり、viewportSize.heightは十分に大きいです)。


2
考えられるすべてのアプローチを試しましたが、これがをクリックしようとしたときに機能した唯一のオプションですtr
Kai


1
最良の解決策imo、+1
Flash Thunder

10

次の方法が役立つことを願っています。バージョン1.9で動作しました

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

これは私のために働いた。これが他の人にも役立つことを願っています


@Jobins john whats waitforload = true?
QadirHussain19年

1
@QadirHussain実際にはページが完全に読み込まれるのを待っています。これは、ページをロードするための特定の時間を設定するのとほとんど同じです。
JobinsJohn19年

6

1.9.2、これは私のために働いた、クリックハンドラがトリガされました:

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

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

それはすべての要素にあるわけではありません。たとえば、<a>にはありません。ボタンにはそこにあります。
unludo 2014年

6

次のような単純なJavaScriptを使用しますevaluate

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

1
実際には、PhantomJS 2.x
BlaM 2016

3

要素を直接クリックすることはできませんでした。代わりに、htmlを調べて、onclickで呼び出された関数を見つけ、その関数を呼び出しました。


addEventListenerを介して関数がアタッチされている場合、関数をどのように見つけ、どのように呼び出すことができますか?
suo6613 2015

2

Document.querySelector(element).click()は、Phantomjs2.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

PhantomJSではダブルクリックも可能です。

推奨

これは、から構成されている解答stovrozとネイティブトリガーdblclickを含むがmousedownmouseupそしてclickイベント(各2本)。

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

他の方法

次の2つの方法は、 dblclickイベントをその前に必要な他のイベントはません。

適応この回答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);

適応この回答Jobinsジョン

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

完全なテストスクリプト


2

最も簡単な方法はjQueryを使用することです。

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

0

JQueryを使用している場合、JQuery UIは、これらをシミュレートするユーティリティを作成しました:jquery-simulate。私はこれをPhantomJSとChromeで使用しています

$ele..simulate( "click" );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.