0

I'm trying to load two scripts that were functionally deferred on account of their type attributes being non-standard i.e. text/javascript/defer. Doing this causes the parser to ignore them so I want to reload them using JavaScript.

My HTML is as below:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>No Title</title>
<meta name="keywords" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">

<script type="text/javascript/defer" src="assets/js/test3.js"></script>
<script type="text/javascript/defer" src="assets/js/test4.js"></script>

<script type="text/javascript" src="assets/js/jquery.js"></script>
<script>

    $(document).ready(function(){

        var defer_js_collection_obj = $("[type='text/javascript/defer']"),
            el_head_rq_obj = $('head'),
            el_head_obj = el_head_rq_obj[0]
        ;

        if(defer_js_collection_obj.length > 0)
        {
            //Reload JavaScript
            defer_js_collection_obj.each(function() {

                var file_src_outer_html_str = this.outerHTML;
                var file_src_res_arr = file_src_outer_html_str.match("src *\= *[\"\']{1}(.*?)[\"\']{1}");
                var file_src_str = file_src_res_arr[1];

                var fileref = document.createElement('script');
                fileref.setAttribute("type", "text/javascript");
                fileref.setAttribute("src", file_src_str);
                document.getElementsByTagName("head")[0].appendChild(fileref);
            });

            //Unload JavaScript with defer tag
            for(var j = defer_js_collection_obj.length-1; j >= 0; j--)
            {
                defer_js_collection_obj[j].parentNode.removeChild(defer_js_collection_obj[j]);
            }
        }

    });

</script>
</head>
<body>
   <div>Load Deferred JavaScript</div>
</body>
</html>

jquery.js is version 1.11.2. test3.js and test4.js reference the javascript files I want to load, and they contain console.log('test3.js is loaded'); and console.log('test4.js is loaded'); respectively.

The issue I'm having is that this script works virtually everywhere else except on Firefox. I'm on a Mac OS X 10.10.5 using Firefox 46.0.1, and I don't see the console.log message when I load the script.

How can I fix this?

5
  • text/javascript/defer is an invalid type. To defer JS you need to use the defer attribute another way: <script defer type="text/javascript" src="assets/js/test3.js"></script> Hacking/altering native functionality will make your code difficult to maintain. In HTML5, you can safely omit the script type anyway, so <script defer src="assets/js/test3.js"></script> would work just fine as text/javascript is the default. Commented Jun 3, 2016 at 17:53
  • Yes, I'm familiar with that, but I prefer doing it this way because of better overall browser support. It works on all the browsers I've tested it in, but not on Firefox so I'm trying to find out why. Commented Jun 3, 2016 at 17:57
  • Have you considered that Firefox simply does not like the malformed type of text/javascript/defer? I just ran a quick test using type="text/javascript/defer" for a simple JS file, and it does not work in FF, but it works in Chrome. Looks like FF just doesn't like it.. nor should it. Commented Jun 3, 2016 at 18:05
  • text/javascript/defer is not going to work because the parser will ignore it on account of it being non-standard syntax: no browser likes it. This is why I'm using the JavaScript code in the question to reload it into the <head> using the standard text/javascript type attribute, which should work in every browser. Commented Jun 3, 2016 at 18:12
  • Try wrapping your code in an IIFE: (function($) { // code }(jQuery)); (instead of $(document).ready(function(){ // code });) The DOM ready might be throwing a wrench in there. Commented Jun 3, 2016 at 18:19

2 Answers 2

1

It might be a mime type issue. Do you happen to see any message in the console stating "not well-formed"? In any case, this seemed to work for me and I agree that your code did not work in FF when I first tried it.

    $(document).ready(function(){
        console.log("main");

        var $body = $($("body")[0]);
        var $scripts = $("[type='text/javascript/defer']");

        $scripts.each(function(){
            var scriptTag = document.createElement("script");
            scriptTag.setAttribute("type", "text/javascript");
            scriptTag.setAttribute("src", $(this).attr("src"));
            $body.append(scriptTag);
        });
    });
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this. I don't see anything in the console stating "not well-formed". I updated the script and it seems to be working now, but I'm not sure why. I might have to introduce a firefox filter to run your script if the browser is firefox.
I'm also getting this warning in the console: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help http://xhr.spec.whatwg.org/
1

Try to append your script at the end of body, so instead do:

document.getElementsByTagName("body")[0].appendChild(fileref);

3 Comments

Thanks. Tried that but it didn't work. I see the scripts before the closing body tag but no console.log message.
Use Firefox Inspectors, to see what your code exactly affect in the page!
As I mentioned above, the code is a simple console.log message, nothing else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.