Matt Bridges
Matt Bridges

Reputation: 171

Function not defined in Tampermonkey

I have the code below but when I click the button it can't find the required function. I'm not great with scopes so I assume it's something to do with that.

Prior to this I had it set as var name = function and it worked until I needed to use the GM_setValue (not defined yet although will be later).

// ==UserScript==
// @name         Futbin Extractor
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.futbin.com/players
// @grant        GM_getValue, GM_setValue
// ==/UserScript==

/* global $ */

(function() {
    'use strict';

//defining all the variables


    function extract (e) {
//all the stuff in this function
    }


    function startExtractor () {
        console.log('Starting Extractor');
        extractorRunning = true;

        $('.player_tr_1').each(function () {
            extract(this);
        });

        $('.player_tr_2').each(function () {
            extract(this);
        });
    };

    function siteSetup () {
        var newBox = '<div id="fiddleBar"><button "startButton" onClick="startExtractor();">Test</button></div>';
        $(newBox).insertBefore('#repTb');
    }



    if (!$('#fiddleBar')) {
        siteSetup;
    } else {
        console.log('Repeating Site Setup');
        setTimeout(siteSetup,100);
    }

})();

Upvotes: 1

Views: 2591

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

There's a couple of issues to address here. Firstly, you can join the two .player_tr_1 and .player_tr_2 selectors in a single jQuery object to loop through together. In addition if (!$('#fiddleBar')) will never hit because a jQuery object always coerces to true. Use the length property if you want to know if the element exists in the DOM.

With regard to your problem, inline event attributes, such as onclick, require the function to be declared in global scope. It's part of the reason they are bad practice and should be avoided. Instead use a delegated event handler, like this:

(function() {
  'use strict';
  
  function extract(e) {
    // all the stuff in this function
  }

  function startExtractor() {
    console.log('Starting Extractor');
    extractorRunning = true;

    $('.player_tr_1, .player_tr_2').each(function() {
      extract(this);
    });
  };
  
  $(document).on('click', '.startButton', function() {
    startExtractor();
  }); 

  function siteSetup() {
    var newBox = '<div id="fiddleBar"><button class="startButton">Test</button></div>';
    $(newBox).insertBefore('#repTb');
  }

  if (!$('#fiddleBar').length) {
    siteSetup();
  } else {
    console.log('Repeating Site Setup');
    setTimeout(siteSetup, 100);
  }
})();

Upvotes: 2

Related Questions