Cliff
Cliff

Reputation: 707

running Greasemonkey-created code in DOM?

I'm completely new to userscripts. I have a small one written to add a link that calls a javascript function:

...
// @require     https://ajax.googleapis.com/ajax/libs/jquery/2.1.3
// ==UserScript==  

    //define functions
    $k = jQuery.noConflict();
    function testFn() {
        alert("Successful test!");
    }

    //add a test link to the DOM
    var testLink = "<a href=\"javascript:testFn()\">TEST LINK</a></div>";
    $k("body").prepend(testLink);

    //add custom functions to the DOM
    var scr = document.createElement("script");
    scr.type = "text/javascript";
    scr.textContent = "$k = jQuery.noConflict();\n" + testFn;    
    $k("body").prepend(scr);

    //add jQuery to the DOM
    var jQueryAdd = document.createElement("script");    
    jQueryAdd.type = "text/javascript";
    jQueryAdd.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"; 
    $k("body").prepend(jQueryAdd);

The script populates my DOM as expected:

<script type="text/javascript">
    $k = jQuery.noConflict();

    function testFn() {
        alert("Testing");
    }
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
<a href="javascript:testFn()">TEST LINK</a>

But, whenever I click on the test link, the function does not execute, and the console throws an error:

ReferenceError: testFn is not defined

I did a fair amount of Googling and, from what I read, this is supposed to be possible. Plus, when I simple save the edited page as its own HTML file, the link works fine. Am I missing something extremely obvious?

Side note: I've also tried putting the jQuery source on the same domain. No dice.

Upvotes: 1

Views: 69

Answers (1)

Fez Vrasta
Fez Vrasta

Reputation: 14835

You have to append the HTML element and not the jQuery object

$k("body").prepend(jQueryAdd[0]);

A better approach, since you are already using jQuery, would be to attach an event listener to your link.

Here a better implementation of your code:

// create a closure and define jQuery as $ inside it
(function($) {

  // create the anchor element, add the `href` attr and a text
  var $testLink = $('<a>', {href: '#0', text: 'click me'});
  // attach an event listener to the generated anchor
  $testLink.on('click', function() {
    alert('hey');
  });
  // append the generated anchor to the body
  $testLink.appendTo('body');

})(jQuery) // calling `(jQuery)` will automatically run this closure

Upvotes: 1

Related Questions