Search code examples
javascriptjquerygreasemonkeytampermonkey

Button click doesn't work in Greasemonkey/Tampermonkey script. Already tried standard mouse events with waitForKeyElements()


I'm trying to click the "Mehr Laden" Button on the URL http://www.sparhandy.de/handy-kaufen/ with Tampermonkey. The Button is located underneath the Smartphone pictures. Here is the script that I wrote so far:

// ==UserScript==
// @name         SparhandyScript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       Nigel
// @match        http://www.sparhandy.de/handy-kaufen/
// @require  http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==

waitForKeyElements ("[data\\-behavior=result\\-paging]", triggerMostButtons);

function triggerMostButtons (jNode) {
    triggerMouseEvent (jNode[0], "mouseover");
    triggerMouseEvent (jNode[0], "mousedown");
    triggerMouseEvent (jNode[0], "mouseup");
    triggerMouseEvent (jNode[0], "click");
    //alert(jNode[0].className);
    //alert(jNode[0].parentNode.className);
}

function triggerMouseEvent (node, eventType) {
    var clickEvent = document.createEvent('MouseEvents');
    clickEvent.initEvent (eventType, true, true);
    node.dispatchEvent (clickEvent);
}

Solution

  • That button is loaded before the jQuery that runs it is ready to fire. So it is not enough to wait for the button in this case. You must also wait for the attached JS to initialize.

    A quick and dirty test shows that, for me, the button is not ready until over a second after page load! (Actual time may vary and I did not attempt to find a suitable state marker (that's for you to do ;). )

    So, adjusting the code to allow for the button to initialize, works for me:

    // ==UserScript==
    // @name        SparhandyScript
    // @match       http://www.sparhandy.de/handy-kaufen/
    // @require     http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
    // @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
    // @grant       GM_addStyle
    // ==/UserScript==
    
    waitForKeyElements ("[data\\-behavior=result\\-paging]", clickButtonAfterDelay);
    
    function clickButtonAfterDelay (jNode) {
        if (document.readyState != "complete")  return true;
        //triggerMouseEvent (jNode[0], "click");
        //-- WARNING: Fixed time may not always work unless it is ridiculously long.
        setTimeout (triggerMouseEvent, 2222, jNode[0], "click");
    }
    
    function triggerMouseEvent (node, eventType) {
        var clickEvent = document.createEvent('MouseEvents');
        clickEvent.initEvent (eventType, true, true);
        node.dispatchEvent (clickEvent);
    }
    


    NOTE: This code will fetch the first additional page of results and then stop. It will not fetch all possible pages; you need a fancier state machine for that.
    It's beyond the scope of this question. If you need help with that part, open a new question (after an honest attempt to solve it yourself).