PhantomJS; щелкните элемент
Как щелкнуть элемент в PhantomJS?
page.evaluate(function() {
document.getElementById('idButtonSpan').click();
});
Это дает мне ошибку "undefined не является функцией..."
Если я вместо этого
return document.getElementById('idButtonSpan');
а затем распечатайте его,
затем он печатает [объект объекта], поэтому элемент существует.
Элемент действует как кнопка, но на самом деле это просто элемент span, а не вход для представления.
Мне удалось нажать эту кнопку, чтобы работать с Каспером, но у Каспера были другие ограничения, поэтому я вернулся к PhantomJS.
Ответы
Ответ 1
.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);
}
Ответ 2
В качестве альтернативы ответу @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
// $.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);
};
}
}
Ответ 3
Это не очень, но я использовал это, чтобы позволить мне использовать 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 достаточно большой).
Ответ 4
Надеемся, что следующий метод будет полезен. Он работал у меня в версии 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;
});
Это сработало для меня. Надеюсь, это будет полезно и для других.
Ответ 5
С 1.9.2
это сработало для меня, нажали обработчики кликов:
var a = page.evaluate(function() {
return document.querySelector('a.open');
});
page.sendEvent('click', a.offsetLeft, a.offsetTop);
Ответ 6
используйте простой JavaScript с evaluate
, что-то вроде этого:
page.evaluate(function() {
document.getElementById('yourId').click();
});
Ответ 7
Я никогда не мог напрямую щелкнуть элемент. Вместо этого я посмотрел на html, чтобы узнать, какая функция была вызвана с помощью onclick, а затем вызвала эту функцию.
Ответ 8
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);
},
Ответ 9
Двойные клики также возможны с помощью PhantomJS.
Рекомендуется
Это адаптировано из ответа stovroz и запускает собственный dblclick
, включая mousedown
, mouseup
и click
события (по два).
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);
Полный тест script
Ответ 10
Самый простой способ - использовать jQuery.
page.evaluate(function() {
page.includeJs("your_jquery_file.js", function() {
page.evaluate(function() {
$('button[data-control-name="see_more"]').click();
});
});
});
Ответ 11
Для тех, кто использует JQuery, пользовательский интерфейс JQuery создал утилиту для имитации: jquery-simulate. Я использую это в PhantomJS и Chrome
$ele..simulate( "click" );