0

I'm injecting Javascript into a page w/ Greasemonkey, doing some processing on the body content (adding markup) then re-inserting the content. The problem is that all the events in the original content are lost, breaking things like onClick events that were added when the page initially loaded.

My original idea was to do this (using jQuery) to just re-add the script tags to the head:

$('script').each(function(s, script) {  $(script).appendTo('head');  })

or just:

$('script').appendTo('head');

I thought this would cause scripts to reload/reeval, but it doesn't work.

A simple example of where I'd like to do this would be on: http://en.m.wikipedia.org/wiki/John_Hardy_%28song%29 I'd need to re-apply the this event found in application.js

 $("h2.section_heading").click(function() {
 // Do something
 }) 
Marcus
  • 2,021
  • 2
  • 21
  • 20
  • 2
    Re-running all the scripts on a page could be a bad idea unless you're sure you know what they do. The behaviors could include AJAX stuff etc. that would not expect to be run twice. Also, even if you do rerun the scripts, they might mark the global context in order to prevent re-application. – Pointy Jul 27 '10 at 23:39

1 Answers1

3

The question of whether and when browsers execute <script> tags that are being added to the page by various methods is a thorny one, made if anything more complicated by jQuery's attempts to work around the issue. You really don't want to get into this.

In any case, as Pointy says, there is no guarantee whatsoever that simply running the page's scripts a second time will make them work with the new content. They may have all sorts of references to old (now replaced) nodes and may not expect to be entered a second time at all.

Don't do processing on markup. HTML string hacking is massively unreliable quite apart from the problem of it replacing all the old objects when you write it back with innerHTML. If you're, say, adding '<span class="highlight">' to the HTML via regex hacks, you've just dug yourself a well of bugs, incompatibilities and potential XSS vulnerabilities.

You've got a perfectly good DOM tree sitting in the browser. Do the processing on that, adding elements and setting attributes over the existing nodes! It's easier, way more reliable, and for many operations much faster.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • Thanks. I'm taking the innerHTML of a block level element that could child elements in it and annotating portions of its innerHTML, (no regexes fwiw). You're right. It's a well of bugs, but I can't use the existing DOM elements since I'm wrapping what was previously just text with new spans. I have to add new DOM elements and I can't limit the text I process to DOM elements that have no children (not without a major rewrite anyway, which I guess isn't out of the question). For the time being, I'd still like to just re-run the initial Javascript and see what happens. I'm targeting Webkit only. – Marcus Jul 28 '10 at 21:30
  • 1
    Adding new spans around pieces of text via DOM methods is trivially easy (however jQuery gives you no help here as it has no handling features for text nodes). Use `splitText` on the Text node twice, to get the stretch of text you want in a node on its own, with leading and trailing text nodes beside it. Then `createElement` a new `` and put the middle text node inside it, inserting the new span into the document where that text node used to be. See eg. the example code in http://stackoverflow.com/questions/1501007/how/1501213#1501213 – bobince Jul 28 '10 at 23:51