【问题标题】:Cannot click element with Phantomjs [duplicate]无法使用 Phantomjs 单击元素 [重复]
【发布时间】:2015-10-28 22:37:49
【问题描述】:

来自帖子:How to ng-click an A directive in a PhantomJS test 我知道我需要创建自己的函数来点击一个元素,但是我该如何使用它呢?

下面的代码给了我错误TypeError: 'undefined' is not a function (evaluating 'click(obj)')

var page = require('webpage').create();
var url = 'http://somesite.com/document.html';

page.open(url, function(status) {
    page.evaluate(function() {
        var obj = document.querySelectorAll('button')[0];
        click(obj);
    });
    console.log(page.content);
    phantom.exit();
});


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

【问题讨论】:

    标签: javascript click phantomjs


    【解决方案1】:

    PhantomJS 有两个上下文。只有通过page.evaluate() 访问的页面上下文才能访问 DOM 并且可以触发合成事件。由于您的click() 函数使用document,因此需要在页面上下文中运行。

    page.evaluate() 是沙盒化的,这就是为什么您不能简单地使用外部定义的变量。您要么需要在页面上下文中定义它们,要么需要以复杂的方式传入它们(因为只有原始对象可以传入和传出页面上下文,而函数不是原始对象)。

    page.open(url, function(status) {
        page.evaluate(function() {
            if (typeof window.click !== "function") {
                window.click = function(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);
                }
            }
            var obj = document.querySelectorAll('button')[0];
            click(obj);
        });
        console.log(page.content);
        phantom.exit();
    });
    

    参考资料:

    【讨论】:

    • 这很有用,我不再收到 TypeError 消息,但是它不能解决问题,即它不会导致单击按钮。我想知道我试图点击的页面是否存在某种 javascript 点击预防,这是一回事吗?
    • @zoltar 点击在 PhantomJS 中总是很棘手。您是否浏览过我链接的问题中的解决方案?特别是,this answer 几乎总是有效。
    • 感谢 Artjom,这是适合我的解决方案。
    【解决方案2】:

    我发现了问题所在。该点击被网站的 javascript 规避。幸运的是,PhantomJS 有一个 sendEvent 函数,可以像真实用户一样发送事件:

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

    通过PhantomJS; click an element找到上述解决方案

    【讨论】:

    • 最好不要复制内容。如果解决方案对您有效,那么最好确认重复。
    【解决方案3】:
        page.evaluate(function () {
            document.getElementById("login").click();
        });
    

    确实有效...不是你的意思?

    【讨论】:

    • .click() 和 click(obj) 有什么区别?
    • 我提到了 js 函数点击 - 而不是你的自定义函数。您声明“...我知道我需要创建自己的函数来单击元素...”,据我了解,这不是真的。
    • element.click() 并不总是有效。
    猜你喜欢
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 2018-06-11
    • 2017-07-25
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多