【问题标题】:PhantomJS; click an element幻影JS;单击一个元素
【发布时间】:2013-03-22 06:44:09
【问题描述】:

如何在 PhantomJS 中单击元素?

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

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

如果我改为

 return document.getElementById('idButtonSpan');

然后打印出来,

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

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

我能够通过单击此按钮来使用 Casper,但 Casper 有其他限制,所以我回到了 PhantomJS。

【问题讨论】:

  • 是时候接受答案了。
  • 有3个答案使用了“dispatchEvent”函数,2个使用了“sendEvent”,一个几乎没用,一个应该是评论。
  • 别忘了#号...
  • 为什么还没有人指出 click() 在 DOM API 中根本不存在,你可能在 jQuery 或类似的 lib 中看到过?
  • 4 年后:答案已接受!我离开了 PhantomJS,所以无法验证答案。但我会接受 58 票是正确的 :) @torazaburo

标签: javascript click phantomjs


【解决方案1】:

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

【讨论】:

  • 如果它是通过 addEventListener 附加的,如何找到该函数以及如何调用它?
【解决方案2】:

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

【讨论】:

  • 用 jQuery 包装 el 可以为您提供这种点击定义。它可以在您的浏览器和 Phantom 中运行。 $(el).click()
  • omg 喜悦的泪水,经过近 12 小时的持续奋斗!闻闻!
  • 对我来说也很好,但必须记住不要在处理完成之前过早退出 PhantomJS。我需要一个简短的脚本来单击一个按钮并退出。在我从 page.onLoadFinished = function() {...}; 中调用 phantom.exit() 之前,这对我不起作用
  • document.querySelector(element).click() 对我来说很好用。
  • 要使用自定义控件,我必须使用 3 个事件制作更复杂的解决方案: function triggerMouseEvent(elm, eventType) { var ev = document.createEvent("MouseEvent"); ev.initMouseEvent( eventType, true /* 气泡 /, true / 可取消 /, window, null, 0, 0, 0, 0, / 坐标 / false , false, false, false, / 修饰键 */ 0 /*left*/, null ); elm.dispatchEvent(ev); } 功能点击(榆树){ triggerMouseEvent(榆树,'mousedown'); triggerMouseEvent(elm, 'mouseup'); triggerMouseEvent(elm, '点击'); }
【解决方案3】:

除了@torazaburo 的响应,您可以在 PhantomJS 中运行时存根 HTMLElement.prototype.click。例如,我们使用 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);
    };
  }
}

【讨论】:

  • 提醒我正在使用 PhantomJs 1.9.7-14 运行 Karma 0.12.17。没有 window._phantom 对象,所以我只是删除了该条件,它按预期工作。
  • 我想知道函数是否应该接受参数以便为鼠标事件设置不同的坐标
【解决方案4】:

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

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

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

【讨论】:

【解决方案5】:

它并不漂亮,但我一直在使用它来允许我使用 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 足够大)。

【讨论】:

  • 尝试了所有可能的方法,这是我尝试点击tr时唯一有效的选项。
  • 使用 phantomjs 1.9.0 并使用 元素
  • 最佳解决方案 imo,+1
【解决方案6】:

希望以下方法有用。它在 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?
  • @QadirHussain 它实际上是在等待页面完全加载。这几乎就像设置一个特定的时间来加载页面。
【解决方案7】:

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

【讨论】:

    【解决方案8】:

    将简单的 JavaScript 与 evaluate 一起使用,如下所示:

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

    【讨论】:

    • 实际上现在是 PhantomJS 2.x 的正确解决方案
    【解决方案9】:

    PhantomJS 也可以双击。

    推荐

    这改编自stovrozthe answer 并触发原生dblclick,包括mousedownmouseupclick 事件(各两个)。

    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事件,不会触发其他应该在它之前的事件。

    改编自this answertorazaburo

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

    改编自this answerJobins 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);
    

    Full test script

    【讨论】:

      【解决方案10】:

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

      $ele..simulate( "click" );
      

      【讨论】:

        【解决方案11】:

        最简单的方法是使用 jQuery。

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

        【讨论】:

          猜你喜欢
          • 2021-07-13
          • 2014-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-17
          • 2013-11-25
          • 1970-01-01
          相关资源
          最近更新 更多