0

I am doing a web application, which is planned to allow a client website to embed javascript from my web application in the following way on its pages:

<script src="http://example.org/showPopup.js"></script>

Suppose my web application is at http://example.org.

I cannot assume that the pages at the client websites have JQuery and Fancybox. So I need to load JQuery and Fancybox in showPopup.js. This is what I have for showPopup.js

var serverName="localhost";
(function() {
    var myScript = document.createElement('script'); 
    myScript.type = 'text/javascript'; 
    myScript.async = false;
    myScript.src = 'http://' + serverName + '/lib/jquery/jquery-1.11.1.min.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body'[0])).appendChild(myScript);

    myScript = document.createElement('script'); 
    myScript.type = 'text/javascript'; 
    myScript.async = false;
    myScript.src = 'http://' + serverName + '/lib/jquery.fancybox/source/jquery.fancybox.pack.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body'[0])).appendChild(myScript);

    var link = $('<a>');
    link.css('display', 'none');
    link.attr('href', 'http://example.org/mypage.html'); 
    link.addClass('fancybox fancybox.iframe');
    link.fancybox();
    link.trigger('click');

})();

Note that the above code works if I use it on a page of my own application. However, I got this error when testing the above code in a page of a client website.

var link = $('<a>');
ReferenceError: $ is not defined

How can I fix it? What is the right way to do this?

Thanks and regards.

----------UPDATE-----------

Qunice provided working code. To make the code fully working, fancybox css must be loaded. Based on Quince's code, I added CSS part. It appears working. Please let me know if there is anything wrong.

(function () {
    var requestedJQuery = false;
    var requestedFancyBoxJs = false;
    var requestedFancyBoxCss = false;

    function requestJQuery() {
        var myScript = document.createElement('script');
        myScript.type = 'text/javascript';
        myScript.async = false;
        myScript.src = 'http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body' [0])).appendChild(myScript);
        requestedJQuery = true;
    }

    function requestFancyboxJs() {
        var myScript = document.createElement('script');
        myScript.type = 'text/javascript';
        myScript.async = false;
        myScript.src = 'http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body' [0])).appendChild(myScript);
        requestedFancyBoxJs = true;
    }

    function requestFancyboxCss() {
        link = document.createElement( 'link' ); 
        link.setAttribute( 'href', '//cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.css' );
        link.setAttribute( 'rel', 'stylesheet' );
        link.setAttribute( 'type', 'text/css' );
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body' [0])).appendChild(link);
        requestedFancyBoxCss = true;
    } 

    function checkDependancies() {
        if (typeof $ === 'undefined' || typeof $.fancybox === 'undefined' || !requestedFancyBoxCss) {

            if(!requestedJQuery && typeof $ === 'undefined') {
                requestJQuery();
            }

            if(!requestedFancyBoxJs && (typeof $ === 'undefined' || typeof $.fancybox === 'undefined')) {
                requestFancyboxJs();
            }

            if(!requestedFancyBoxCss) {
                requestFancyboxCss();
            }           

            setTimeout(function () {
                checkDependancies();
            }, 1);

        } else {
            displayFancyBox();
        }
    }


    function displayFancyBox() {
        var link = $('<a>');
        link.css('display', 'none');
        link.attr('href', 'http://jsfiddle.net/');
        link.addClass('fancybox fancybox.iframe');
        link.fancybox();
        link.trigger('click');
    }

    checkDependancies();

})()

Hope this helps someone else.

curious1
  • 14,155
  • 37
  • 130
  • 231

1 Answers1

2

Main issue is that using $ or fancybox when it is not defined will cause an error and cause the script to stop.

The next problem is that the script needs time to download and run jQuery and fancybox so i would suggest testing for jQuery and fancyBox and if it is not there adding a timeOut before another test.

You could also use a flag so you only try to get the script you are missing.

(function () {
    var requestedJQuery = false;
    var requestedFancyBox = false;

    function requestJQuery() {
        var myScript = document.createElement('script');
        myScript.type = 'text/javascript';
        myScript.async = false;
        myScript.src = 'http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body' [0])).appendChild(myScript);
        requestedJQuery = true;
    }

    function requestFancybox() {
        var myScript = document.createElement('script');
        myScript.type = 'text/javascript';
        myScript.async = false;
        myScript.src = 'http://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.pack.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body' [0])).appendChild(myScript);
        requestedFancyBox = true;
    }

    function checkDependancies() {
        if (typeof $ === 'undefined' || typeof $.fancybox === 'undefined') {
            console.log("no dependanices");            
            if(!requestedJQuery && typeof $ === 'undefined')
            {
                requestJQuery();
            }

            if(!requestedFancyBox && (typeof $ === 'undefined' || typeof $.fancybox === 'undefined'))
            {
                requestFancybox();
            }

            setTimeout(function () {
                checkDependancies();
            }, 1);
        } else {
            displayFancyBox();
        }
    }

    function displayFancyBox() {
        console.log("got dependanices");
        var link = $('<a>');
        link.css('display', 'none');
        link.attr('href', 'http://jsfiddle.net/');
        link.addClass('fancybox fancybox.iframe');
        link.fancybox();
        link.trigger('click');
    }

    checkDependancies();

})()

http://jsfiddle.net/leighking2/y9Lqtec9/

Quince
  • 14,790
  • 6
  • 60
  • 69
  • Thanks for the clear explanation and working code. This will surely help more people! Thanks, again!!! – curious1 Nov 07 '14 at 16:47
  • +1 - @curious1 : I think you should be appending the fancybox css file too – JFK Nov 07 '14 at 18:33
  • @jfk yeah agree with that should really get all dependencies in there. Just add it when doing the fancy box js request – Quince Nov 07 '14 at 18:40
  • JFK and Quince, thank you both for mentioning the CSS file. To make the above code truly useful, the fancybox css file has to be loaded too. I am struggling with how to do it now. Quince, any clean way to add the css file by expanding your code? Regards. – curious1 Nov 07 '14 at 21:15
  • @Qunice, I updated my code with css loading. Do you mind see if there is anything not right? Thanks! – curious1 Nov 08 '14 at 02:11
  • On my mobile so can't text it but it looks tight only thing to put is var before link in the CSS loading so it doesn't get created as global – Quince Nov 08 '14 at 08:38