Search code examples
javascripthtmlmetaprogrammingscript-tag

How to delay script tag until other script tag has run


I've been experimenting with metaprogramming in webpages, and need to delay a script tag from running until just after another script tag has been run. However, the script tag needs to be loaded first or both of them will fail.

Shortened and more readable version of what I'm trying to do:

<script defer>
    w=function(){
        <stuff that gives a parser error until modified by the next script tag>
    }
</script>
<script>
    <stuff that changes the previous script tag and any other script tags that ever will be added via the DOM
    so it doesn't give a parser error>
</script>
<button onclick='w()'></button>

This would work perfectly well, except that the button's onclick attribute fails because the button was loaded before the first script tag was run. Thanks in advance!

(EDIT: I linked a pastebin to show the full version of my code, it might clear things up a bit since it seems my summed-up version wasn't very good.


Solution

  • As suggested by @meagar in the comments, if you don't mind changing the type property of your "not actually javascript" script blocks you can do something like this:

    <script type='derpscript'>
      var derp;
      var w=function(){alert('hello')}; 
      derp||=5;
      console.log(derp);
    </script>
    
    <script>
    function compileDerps() {
      // find all derpscript script tags
      var x = document.querySelectorAll('script[type=derpscript]');
      for(var i=0;i<x.length;i++){
        meta=x[i].text
        while(true){
          pastmeta=meta;
          console.log(exc=regex.exec(meta))
          if(exc){
            meta=meta.replace(regex,exc[1]+'='+exc[1]+'||');
          }
          if(pastmeta==meta){break;}
        }
        // make a new javascript script tag to hold the compiled derp
        var s = document.createElement('script');
        s.text = meta;
        document.body.appendChild(s);
        // delete the derpscript tag
        x[i].parentNode.removeChild(x[i]);
      }
    }
    
        //stuff that changes the previous script tag and any other script tags that ever will be added via the DOM
        var regex=/([a-zA-Z$_][a-zA-Z$_1-9]*)(\|\|\=)/;
        var meta;
        var pastmeta='';
        var exc='';
    
        compileDerps();
    </script>
    
    <button onclick='w()'>THIS IS W</button>