2015-10-19 3 views
4

Из сообщения: How to ng-click an A directive in a PhantomJS test Я понимаю, что мне нужно создать свою собственную функцию, чтобы щелкнуть элемент, но как его использовать?Не удается щелкнуть элемент с помощью Phantomjs

Следующий код дает мне ошибку 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); 
} 

ответ

1

я понял проблему. Щелчок был обойден 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

+0

Лучше не дублировать контент. Если решение сработало для вас, тогда лучше всего подтвердить дубликат. –

0
page.evaluate(function() { 
     document.getElementById("login").click(); 
    }); 

делает работу ... Не то, что вы имеете в виду?

+0

чем разница между .click() и нажмите (OBJ)? – zoltar

+0

Я использую функцию js click - не ваша пользовательская функция. Вы заявляете «... я понимаю, что мне нужно создать свою собственную функцию, чтобы щелкнуть элемент ...», что не так, как я понимаю. – user1515791

+3

'element.click()' не всегда работает. –

4

PhantomJS имеет два контекста. Только контекст страницы, доступ к которому осуществляется через page.evaluate(), имеет доступ к DOM и может инициировать синтетические события. Поскольку ваша функция click() использует document, ее необходимо запустить в контексте страницы.

page.evaluate() is sandboxed, поэтому вы не можете просто использовать переменные, определенные снаружи. Вам нужно либо определить их в контексте страницы, либо вам необходимо передать их сложным образом (поскольку только примитивные объекты могут быть переданы и выведены из контекста страницы, а функции не являются примитивными объектами).

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

Ссылки:

+0

Это полезно, и я больше не получаю сообщение TypeError, однако оно не решает проблему, то есть не приводит к щелчку кнопки. Мне интересно, есть ли какая-то защита от javascript-кликов, идущая на странице, которую я пытаюсь щелкнуть, это что-то? – zoltar

+1

@zoltar Щелчок всегда сложный в PhantomJS. Прошли ли вы решения в вопросе, который я связал? В частности, [этот ответ] (http://stackoverflow.com/a/24026636/1816580) работает почти всегда. –

+0

Спасибо Artjom, это решение, которое работает для меня. – zoltar

Смежные вопросы