¿Cómo hago clic en un elemento en PhantomJS?
page.evaluate(function() {
document.getElementById('idButtonSpan').click();
});
Esto me da un error "indefinido no es una función ..."
Si yo en cambio
return document.getElementById('idButtonSpan');
y luego imprimirlo,
luego imprime [objeto objeto], por lo que el elemento existe.
El elemento actúa como un botón, pero en realidad es solo un elemento de intervalo, no una entrada de envío.
Pude hacer que este botón funcionara con Casper, pero Casper tenía otras limitaciones, así que volví a PhantomJS.
javascript
click
phantomjs
usuario984003
fuente
fuente
click()
no existe en DOM API en absoluto, probablemente lo vio en jQuery o alguna lib como esa?Respuestas:
.click()
no es estándar. Necesita crear un evento y enviarlo: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); }
fuente
el
con jQuery le da esta definición de clic. Funcionará en su navegador y en Phantom.$(el).click()
Alternativamente a la respuesta de @ torazaburo, puede stub
HTMLElement.prototype.click
cuando se ejecuta en PhantomJS. Por ejemplo, usamos PhantomJS + QUnit para ejecutar nuestras pruebas y en nuestroqunit-config.js
tenemos algo como esto: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); }; } }
fuente
window._phantom
objeto, así que eliminé esa condición y funcionó como se esperaba.No es bonito, pero he estado usando esto para permitirme usar jQuery para la selección:
var rect = page.evaluate(function() { return $('a.whatever')[0].getBoundingClientRect(); }); page.sendEvent('click', rect.left + rect.width / 2, rect.top + rect.height / 2);
pero siempre puede reemplazar
$(s)[0]
condocument.querySelector(s)
si no usa jQuery.(Depende de que el elemento esté en vista, es decir, su viewportSize.height es lo suficientemente grande).
fuente
tr
.+1
Espero que el siguiente método sea útil. Me funcionó en la versión 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; });
Esto funcionó para mí. Espero que esto también sea útil para otros
fuente
Con
1.9.2
esto funcionó para mí, se activaron los controladores de clic:var a = page.evaluate(function() { return document.querySelector('a.open'); }); page.sendEvent('click', a.offsetLeft, a.offsetTop);
fuente
use JavaScript simple con
evaluate
algo como esto:page.evaluate(function() { document.getElementById('yourId').click(); });
fuente
Nunca pude hacer clic directamente en el elemento. En cambio, miré el html para encontrar qué función se llamó con onclick, y luego llamé a esa función.
fuente
Document.querySelector (elemento) .click () funciona cuando se usa 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); },
fuente
También es posible hacer doble clic con PhantomJS.
Recomendado
Esto está adaptado de la respuesta de stovroz y desencadena un nativo que
dblclick
incluye los eventosmousedown
,mouseup
yclick
(dos de cada uno).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);
Otras maneras
Las siguientes dos formas solo desencadenan el
dblclick
evento, pero no los otros eventos que deberían precederlo.Adaptado de esta respuesta de 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);
Adaptado de esta respuesta de 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);
Guión de prueba completo
fuente
La forma más sencilla es usar jQuery.
page.evaluate(function() { page.includeJs("your_jquery_file.js", function() { page.evaluate(function() { $('button[data-control-name="see_more"]').click(); }); }); });
fuente
Para aquellos que usan JQuery, la interfaz de usuario de JQuery creó una utilidad para simularlos: jquery-simulate . Yo uso esto en PhantomJS y Chrome
$ele..simulate( "click" );
fuente