82

如何单击 PhantomJS 中的元素?

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

这给了我一个错误“未定义不是函数......”

如果我改为

 return document.getElementById('idButtonSpan');

然后打印出来,

然后它打印[object object],所以元素确实存在。

该元素充当按钮,但它实际上只是一个 span 元素,而不是提交输入。

我可以点击这个按钮来使用 Casper,但 Casper 有其他限制,所以我回到了 PhantomJS。

4

11 回答 11

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);
}
于 2013-04-11T12:06:10.853 回答
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);
    };
  }
}
于 2013-07-22T14:18:10.137 回答
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);

但如果不使用 jQuery ,你总是可以替换$(s)[0]为。document.querySelector(s)

(它确实依赖于考虑到的元素,即您的 viewportSize.height 足够大)。

于 2014-06-03T23:27:29.807 回答
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;
});

这对我有用。希望这对其他人也有用

于 2014-08-07T11:00:30.247 回答
6

这对1.9.2我有用,点击处理程序被触发:

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

page.sendEvent('click', a.offsetLeft, a.offsetTop);
于 2013-11-16T19:41:54.737 回答
6

使用简单的 JavaScript evaluate,如下所示:

page.evaluate(function() {
    document.getElementById('yourId').click();
});
于 2016-03-09T10:04:11.163 回答
3

我永远无法直接单击该元素。相反,我查看了 html 以找到使用 onclick 调用的函数,然后调用了该函数。

于 2013-04-02T08:29:50.447 回答
2

Document.querySelector(element).click() 在使用 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);
},
于 2016-01-15T15:46:40.253 回答
2

PhantomJS 也可以双击。

受到推崇的

这改编自stovroz的答案,并触发了包括,和事件(每个两个)的本地。dblclickmousedownmouseupclick

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

其他方法

以下两种方式只触发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 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);

完整的测试脚本

于 2016-06-13T09:16:33.083 回答
2

最简单的方法是使用 jQuery。

page.evaluate(function() {
  page.includeJs("your_jquery_file.js", function() {
    page.evaluate(function() {
      $('button[data-control-name="see_more"]').click();
    });
  });
});
于 2017-06-21T09:25:55.153 回答
0

对于使用 JQuery 的用户,JQuery UI 创建了一个实用程序来模拟这些:jquery-simulate。我在 PhantomJS 和 Chrome 中使用它

$ele..simulate( "click" );
于 2016-10-24T19:39:38.373 回答