6

I wrote a script that adds the number, contained in the image source URL, to the page. It works great!

But, I also want it to run on a page that has AJAX-driven tabs.
I've tried playing around with waitForKeyElements but I can't figure out how to make it work, and I don't understand jQuery.

When I use #dolls it puts all contents of all tabs on the page... when I use div.dolls it disables the button to load the dolls.

// ==UserScript==
// @name        Dex# of Pokedolls
// @namespace   http://trueidiocy.us
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=collection
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=giveaway
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=regional
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=shop
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=local&market=sell*
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=local&market=buy*
// @include     http://www.thepikaclub.co.uk/adopt/trainercard.php?trainer=*
// @version     1
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       none
// ==/UserScript==

 waitForKeyElements (
 "div.dolls"           //also tried #dolls
, showdexno
);

function showdexno (jNode) {
var imgs = document.getElementsByTagName('img');     

for (var i = imgs.length - 1; i >= 0; i--) {
  if (imgs[i].src.indexOf('overworld') > -1) {
     var textNode = document.createElement('b');

var numtext=imgs[i].src.match(/\d+/g)

  textNode.innerHTML = numtext;    
  imgs[i].parentNode.appendChild(textNode, imgs[i]);     
 }
} 
}


I'm probably just not using the right syntax or something, but I'm totally lost.

I'm testing the script on this page, and it needs to trigger when the Load Pokédolls button is clicked on the Pokédolls tab.

You can view that target page without having to login.

I'm assuming that after I get this working I would just throw everything into an if statement:

 If location is trainer card wait for tab
 else just run the code

So, what am I doing wrong? How do I use waitForKeyElements for this? Or is there another way?

ETA: one more problem... On one page this shows the numbers right next to the pictures which is perfect - BUT - on other pages that have text under the images it adds it to the existing text. How do I make it be right next to the picture every time?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Kat Cox
  • 3,469
  • 2
  • 17
  • 29

1 Answers1

8

Okay, I think I see what you are trying to do. But first, the question code has two big problems:

  1. The script uses jQuery, but the target page also uses jQuery. So, when the script operates in @grant none mode, either the script will crash, or the page will crash, or both. Defaulting to @grant none was a colossal mistake by the lead GM dev and, even if you are not using jQuery, you would be wise to avoid that mode. Otherwise, your script will crash, it's just a matter of what future change does it in.
  2. Fixed: waitForKeyElements is passed a callback function named showdexno, but there is no showdexno defined in the script! (or on the page that I checked.)


waitForKeyElements() operates by looking for elements that match the selector and then feeding those elements, one at a time, to the callback function. This means that things like getElementsByTagName or seldom needed in the callback.

For example, if you wanted to act on a bunch of images like this:

target images


You would determine the HTML structure, paying attention to any id or class attributes. In this case, it looks like:

<div id="dolls">
  <center>
    <table>
      <tr>
        <td>
          <img class="attached" title="Quantity = 5" src="http://www.thepikaclub.co.uk/dex/images/icon/overworld/1.png">
        </td>
        <td>
          <img class="attached" title="Quantity = 18" src="http://www.thepikaclub.co.uk/dex/images/icon/overworld/2.png">
        </td>
... ...


And you apparently want only those images that have overworld in the src.

So, a good CSS/jQuery selector to choose might be #dolls td > img.attached[src*='overworld'].

The jNode passed to your waitForKeyElements callback would then be the image itself. Images are passed in one at a time.

Putting it all together, a script to append the png file number would be like:

// ==UserScript==
// @name        Dex# of Pokedolls
// @namespace   http://trueidiocy.us
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=collection
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=giveaway
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=regional
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=shop
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=local&market=sell*
// @include     http://www.thepikaclub.co.uk/adopt/dolls.php?action=local&market=buy*
// @include     http://www.thepikaclub.co.uk/adopt/trainercard.php?trainer=*
// @version     1
// @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==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/
waitForKeyElements (
    "#dolls td > img.attached[src*='overworld']", 
    appendImageNumber
);

function appendImageNumber (jNode) {
    var numtext = jNode.attr ("src").match (/\d+/g);

    jNode.after ('<b>' + numtext + '</b>');
}

Eliminate the .attached if you want more (¿all?) of the images.

Reference:

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • I goofed in my code above... in my script get_span_content was showdexno... but I had already deleted it cause it didn't work so forgot to change in post what I copied from example... I'll fix that now... and yeah I thought the 2 jquerys could cause probs but couldn't find what I'd read about it – Kat Cox Oct 08 '13 at 07:26
  • Greasemonkey automatically added the grant line... I just recently updated from .92 (I think...9 something anyways) and think I'll just leave out that line... all my old scripts work fine without it. – Kat Cox Oct 08 '13 at 07:33
  • Working pretty good... but yeah I need all the doll images to show numbers... stinking trade system requires you to type the dex# of the doll you want to trade for, and if you don't play pokemon you have no idea what any of those dolls are... would it look like `"#dolls td > img[src*='overworld']"` – Kat Cox Oct 08 '13 at 07:56
  • You need the grant line, `@grant GM_addStyle`, for sure for this page. You would be wise to use that line in all your scripts, even if they appear to work (for now). And, yes, `"#dolls td > img[src*='overworld']"` is what it would look like. – Brock Adams Oct 08 '13 at 08:07
  • I noticed I needed that... now my only problem is that I added an `if` to check and run that version if it's on the trainer card page... but my `else { appendImageNumber }` doesn't work on the non-ajax pages... I could use my previous code on those pages - except the placement of the text wasn't where I wanted it... God, I wish jQuery didn't confuse me so bad - js, basic, php, no problem... just something about jQuery... back to trying to solve this part of the problem before someone answers and beats me to it lol – Kat Cox Oct 08 '13 at 08:25
  • Oh, and for some reason this only works if I use a link to go to the page... if I refresh the page the load dolls button is grayed out... – Kat Cox Oct 08 '13 at 08:27
  • Actually, waitForKeyElements will work on non ajax pages too. You might have to adjust the selector for them though. You can have more than waitForKeyElements call in a script. ... The button being greyed out looks like something that the site might be doing on purpose. It's easily defeated though (remove the `disabled` attribute). Open new questions for these new wrinkles, if necessary. – Brock Adams Oct 08 '13 at 08:40
  • Okay, thanks... I thought that the button problem didn't happen before the script, but when I turned it off it still did it... it IS a slightly buggy site... – Kat Cox Oct 08 '13 at 08:45
  • Thanks for the edits... but next time could you maybe leave just a little of my personality in there please? lol – Kat Cox Oct 08 '13 at 09:16
  • Okay, but pretty sure that's against SO policy. ;) Also, we're tech nerds, tangential chatter annoys us. Just the facts, Ma'am, as simply and clearly as you can state them. The exceptions are mostly on [meta], like [this one](http://meta.stackexchange.com/a/152754/148310). – Brock Adams Oct 08 '13 at 09:36