Clicking a button on a page using a Greasemonkey/userscript in Chrome

I'm going to be as absolutely verbose here as possible as I've run into a few solutions that didn't end up panning out. Please keep in mind that I don't know Javascript. I know basic HTML and CSS. I don't have any actual programming background but I'm trying to learn bit by bit by researching basic tasks like this. Please talk to me like I'm an idiot. Any lingo I throw around in this post I learned while researching this specific issue. I'm writing this userscript as a personal project and to share with some friends.

What I'm trying to do.

I'm trying to write a userscript for Chrome/Greasemonkey (Chrome is my target browser) that will click the Refresh button on the Battlefield 3 server browser. For those of you that don't know, Battlefield 3 uses a web site paired with a browser plugin for VOIP and actually launching the game via a server browser. The bulk of it seems to be fairly straight forward HTML arranged in tables.

The idea is that when viewing the main page for a server that is full, the script will click the Refresh button every three seconds or so until the page reports an open spot on the server, then stop the refresh loop and click the join server button. I've already got the part of the script running that polls the server current and maximum players then assigns them to their own variables.

At this point I'm trying to get a click to work in the console so I can actually put it to some use in my script and am having zero luck.

The code I'm trying to manipulate.

This is the div for the button that I'm trying to click pulled from the Chrome dev tools:

<div class="serverguide-header-refresh-button alternate show"> 
<div type="reset" class="common-button-medium-grey">
<p style="position: relative;">
<a href="/bf3/servers/show/c7088bdc-2806-4758-bf93-2106792b34d8/">Refresh </a>
</p>
</div>
</div>

(That link is not static. It's a link to a specific server page)

What I've tried.

To actually find the button I'm using getElementsByClassName. It doesn't have a unique ID but the class is unique to that element on this particular page so getElementsByClassName("serverguide-header-refresh-button")[0] is pulling the proper div each time. It's getting the script to perform any actual action on the button that's the problem.

document.getElementsByClassName("serverguide-header-refresh-button")[0].click();

I now realize this didn't work because it's not a conventional submit button. I don't understand the specifics of the standard here but I get that it doesn't support the .click() method.

function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}

// the guts of this userscript
function main() {
  unsafeWindow.jQuery('.serverguide-header-refresh-button')[0].click();
}

// load jQuery and execute the main function
addJQuery(main);

This is simply unsafeWindow.jQuery('.serverguide-header-refresh-button').click(); wrapped in some code to load jQuery for userscripts. It was a bit I picked up elsewhere but was told it would only work if jQuery was loaded on the page. I figured it was worth a try. This is one of those I have no idea what I'm doing shots in the dark and it didn't work. I tried the same thing below with another snippet of jQuery code I picked up:

function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}

// the guts of this userscript
function main() {
   var evObj = document.createEvent('Events');
      evObj.initEvent("click", true, false);
      document.getElementsByClassName('serverguide-header-refresh-button')[0].dispatchEvent(evObj);
}

    // load jQuery and execute the main function
addJQuery(main);

Both of these return Undefined in the Chrome and Firebug consoles.

So, would anyone be so kind as to help me create a bit of code for this script to press the Refresh button on this page?

Answers:

Answer

Note:

  1. jQuery .click() does not work reliably on click events that were not set via jQuery in the first place.

  2. You need to create the right kind of event; createEvent('Events') is not the way.

  3. As Jim Deville pointed out, the link pseudo-button was not being selected.

  4. You do not need jQuery for this (so far).

  5. Make sure that the "Refresh" control is loaded statically for the test code as shown in the question. If it's AJAXed in, the click attempt may fire too soon.

Putting that all together, the following code should work. But beware that some sites (like certain Google apps) use funky, state-sensitive designs -- which require a sequence of events.

var refreshBtn = document.querySelector (
    "div.serverguide-header-refresh-button div[type='reset'] a"
);
var clickEvent = document.createEvent ('MouseEvents');
clickEvent.initEvent ('click', true, true);
refreshBtn.dispatchEvent (clickEvent);
Answer

so, you are on the right track, but you keep grabbing the DIV not the A tag. To click on the "button" (link in this case), you have to click on the actual link because it won't tunnel down to the elements contained in the DIV.

document.querySelector('serverguide-header-refresh-button a')

Should get you the A element to click on. From jQuery $('serverguide-header-refresh-button a').click(); should work.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.