PhantomJS; 요소를 클릭


81

PhantomJS에서 요소를 어떻게 클릭합니까?

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

"정의되지 않은 것은 함수가 아닙니다 ..."라는 오류가 발생합니다.

대신 내가

 return document.getElementById('idButtonSpan');

인쇄하고

그런 다음 [object object]를 인쇄하므로 요소가 존재합니다.

요소는 버튼 역할을하지만 실제로는 제출 입력이 아닌 스팬 요소 일뿐입니다.

이 버튼을 클릭하여 Casper와 함께 작동하도록 할 수 있었지만 Casper에는 다른 제한 사항이 있으므로 PhantomJS로 돌아 왔습니다.


28
대답을 받아 들일 시간입니다.

"dispatchEvent"기능을 사용하는 3 개의 답변, "sendEvent"를 사용하는 2 개의 답변, 실질적으로 쓸모없는 답변 1 개, 주석이어야하는 답변 1 개가 있습니다.
redbeam_

# 기호 ... 잊지 마세요
GracefulCode

click()DOM API에 전혀 존재하지 않는 것을 아직 아무도 지적 하지 않은 이유는 무엇입니까? 아마도 jQuery 또는 이와 유사한 lib에서 보았을 것입니다.
YemSalat

4 년 후 : 답변 가능! 나는 PhantomJS에서 벗어 났기 때문에 답을 확인할 수 없었습니다. 그러나 나는 58 개의 찬성표가 맞다는 것을 받아 들일 것이다. :) @torazaburo
user984003

답변:


68

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

9
eljQuery로 래핑 하면 이러한 클릭 정의가 제공됩니다. 브라우저와 Phantom에서 작동합니다. $(el).click()
Bluu 2013-06-05

3
이걸로 거의 12 시간의 지속적인 투쟁 끝에 기쁨의 눈물을 흘리 셨습니다! 킁 킁킁!
user1323136

1
나에게도 잘 작동했지만 처리가 완료되기 전에 PhantomJS를 너무 빨리 종료하지 않는 것을 기억해야합니다. 버튼 하나만 클릭하고 종료하려면 간단한 스크립트가 필요했습니다. 이것은 page.onLoadFinished = function () {...} 내에서 phantom.exit ()를 호출 할 때까지 작동하지 않습니다.
gregko

document.querySelector (element) .click ()은 저에게 잘 작동합니다.
GracefulCode

사용자 지정 컨트롤을 사용하려면 3 개의 이벤트로 더 복잡한 솔루션을 만들어야했습니다. function triggerMouseEvent (elm, eventType) {var ev = document.createEvent ( "MouseEvent"); ev.initMouseEvent (eventType, true / * bubble /, true / cancelable /, window, null, 0, 0, 0, 0, / 좌표 / false, false, false, false, / 수정 자 키 * / 0 / * left * /, 없는 ); elm.dispatchEvent (ev); } function click (elm) {triggerMouseEvent (elm, 'mousedown'); triggerMouseEvent (elm, 'mouseup'); triggerMouseEvent (elm, 'click'); }
A-bobkov

34

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

1
PhantomJs 1.9.7-14와 함께 Karma 0.12.17을 실행하고 있습니다. window._phantom개체 가 없으므로 해당 조건을 제거하고 예상대로 작동했습니다.
BradGreens 2014

함수가 MouseEvent에 대해 다른 좌표를 설정하기 위해 매개 변수를 허용해야하는지 궁금합니다
ffflabs

16

예쁘지는 않지만 선택을 위해 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가 충분히 큽니다).


2
가능한 모든 접근 방식을 시도했으며 이것은를 클릭하려고 할 때 저에게 효과가 있었던 유일한 옵션입니다 tr.
Kai

phantomjs 1.9.0 및 <a> 요소 작업
redbeam_

1
최고의 솔루션 imo,+1
Flash Thunder

10

다음 방법이 유용하기를 바랍니다. 버전 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?
Qadir Hussain

1
@QadirHussain 실제로 페이지가 완전히로드되기를 기다리고 있습니다. 페이지를로드 할 특정 시간을 설정하는 것과 거의 같습니다.
Jobins 존

6

함께 1.9.2이 나를 위해 일한, 클릭 핸들러가 트리거되었다 :

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

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

모든 요소에있는 것은 아닙니다. 예를 들어 <a>에는 없습니다. 버튼에 있습니다.
unludo

6

evaluate다음과 같이 간단한 JavaScript를 사용 하십시오.

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

1
실제로는 이제 올바른 용액 PhantomJS 2.x를 가진 지금
BLAM

3

요소를 직접 클릭 할 수 없었습니다. 대신 html을보고 onclick으로 어떤 함수가 호출되었는지 확인한 다음 해당 함수를 호출했습니다.


addEventListener를 통해 연결된 경우 함수를 어떻게 찾고 호출하는 방법은 무엇입니까?
Suo6613

2

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

2

PhantomJS로 더블 클릭도 가능합니다.

추천

이것은 stovroz 의 답변 에서 수정 되었으며 , 및 이벤트 (각각 2 개)를 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 이벤트를 뿐 선행해야하는 다른 이벤트는 하지 않습니다.

에서 적응 이 답변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 존 :

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

전체 테스트 스크립트


2

가장 쉬운 방법은 jQuery를 사용하는 것입니다.

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

0

JQuery를 사용하는 사람들을 위해 JQuery UI는이를 시뮬레이션하는 유틸리티를 만들었습니다 : jquery-simulate . PhantomJS와 Chrome에서 사용합니다.

$ele..simulate( "click" );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.