gamblor01 Posted May 23, 2011 Share Posted May 23, 2011 Hi all, I have done some search on the net and found some solutions to dynamically load up JavaScript files. It looks pretty simple, just reference the HEAD element of the document via DOM and append a child. I only want to do this in the case that a particular JavaScript file is available, and I believe I have an AJAX solution do that. Here are the two functions that I wrote: function isReachableURL(url) { var request = false; if (window.XMLHttpRequest) { request = new XMLHttpRequest; } else if (window.ActiveXObject) { request = new ActiveXObject("Microsoft.XMLHttp"); } if (request) { request.open("GET", url); if (request.readyState == 4 && request.status == 200) return true; } return false; } function addJavaScriptFile(path) { var fileRef = document.createElement('script'); fileRef.setAttribute("type","text/javascript"); fileRef.setAttribute("src", path); fileRef.setAttribute("id", gpsGateDomId) document.getElementsByTagName("head")[0].appendChild(fileRef); } Armed with these two functions, I can test for the existence of .js file on an external server and reference it if it's reachable. The reason I am doing this is to facilitate some GPS functionality in the application that I work on. We are relying on a program called GpsGate to gather coordinates from a USB/bluetooth GPS device. GpsGate works by launching a small HTTP server that hosts some JavaScript files, and via cross scripting you can obtain your position, altitude, etc. More info can be found here: http://forum.gpsgate.com/topic.asp?TOPIC_ID=6102 Their server is ALWAYS at http://localhost:12175/javascript/GpsGate.js -- assuming that GpsGate is running of course! So my goal is to add a script tag to my page that references http://localhost:12175/javascript/GpsGate.js as the source. In fact, I did this and all of my code works fine. The problem is, for users that do not have GpsGate installed, the browser will output an error that it was unable to load that JavaScript file. For example, if you go into the developer tools in Chrome (CTRL+SHIFT+I) and look, there will be an error that says: GET http://localhost:12175/javascript/GpsGate.js undefined (undefined) Of course other developers are complaining about this and our users will no doubt complain eventually as well. So instead of placing this file into the HEAD tag of the page every time, I want to append it dynamically (only in the case that the user has chosen to do something which involves GPS). I am able to dynamically add the child element to HEAD -- I see it get added in Chrome's debugger if I inspect the children of document.getElementsByTagName("head")[0]. However, it still seems that the typeof(GpsGate) is undefined. If I'm understanding correctly, the SCRIPT tag seems to be getting appended under HEAD, but it's almost as if that script is never executed. Do I need to do something special for that script file to execute after appending it in the DOM tree? If it helps, here is the script file that I see when I hit http://localhost:12175/javascript/GpsGate.js in my browser. It's some strange anonymous function syntax that I'm not familiar with in JavaScript. Any body know what to do to get this function to execute in JavaScript after appending the SCRIPT tag in the DOM tree? I added an alert() in this script to see if it would print anything when I added it in the DOM tree and it did not -- reinforcing the idea that it's being appended in DOM but never executed. If I add the script manually into the HEAD tag then it does show my alert box. // // Copyright Franson Technology AB - GpsGate.com // franson.com - gpsgate.com // (function() { if (typeof(GpsGate) == 'undefined') { GpsGate = {}; } var _url = 'http://localhost:12175/gps'; var _scriptCounter = 0; function buildQueryString(params) { var strParams = ''; for (prop in params) { strParams += '&' + encodeURIComponent(prop) + '=' + encodeURIComponent(params[prop]); } return strParams; } function xssCall(methodName, params, callback) { var id = _scriptCounter++; var scriptNodeId = 'GpsGateXss_' + id; var poolName = methodName + '_' + id; GpsGate.Client._callback[poolName] = function(/*arguments*/) { var scriptNode = document.getElementById(scriptNodeId); scriptNode.parentNode.removeChild(scriptNode); delete GpsGate.Client._callback[poolName]; scriptNode = null; callback.apply(this, arguments); }; var callUrl = _url + '/' + methodName + '?jsonp=' + ('GpsGate.Client._callback.' + poolName) + buildQueryString(params); var script = document.createElement('script'); script.type = 'text/javascript'; script.id = scriptNodeId; // script.charset = 'utf-8'; // necessary? var noCache = '&noCache=' + ((new Date()).getTime().toString().substr(5) + id); script.src = callUrl + noCache; // todo: use this method on non-conforming browsers? (altough both IE6 and PC-Safari seems to work anyway) // document.write('<script src="' + src + '" type="text/javascript"><\/script>'); document.getElementsByTagName('head')[0].appendChild(script); script = null; } // API GpsGate.Client = { Copyright: 'Franson Technology AB - GpsGate', getGpsInfo: function(callback) { xssCall('getGpsInfo', {}, callback); }, getVersion: function(callback) { xssCall('getVersion', {}, callback); }, // ----- _callback: {} }; })(); Quote Link to comment https://forums.phpfreaks.com/topic/237245-dynamically-loading-javascript-files/ Share on other sites More sharing options...
gamblor01 Posted May 23, 2011 Author Share Posted May 23, 2011 Hmm...well I sort of got things working by using dojo. The following works to dynamically load the external .js file: function addJavaScriptFile(path) { dojo.io.script.get ( { url: gpsGateURL, load: function() { // signal that this has been loaded already gpsGateLoaded = true; } }); } However, it turns out my isReachableURL() function (which was previously commented out) doesn't work. Apparently this is due to the same-origin policy: http://stackoverflow.com/questions/5573360/test-url-availability-with-javascript This is a bit of a bummer because I'm not sure how to solve this yet. I can't let the server test for the existence of the URL because the whole point is that the URL is local to the client (i.e. localhost is the client system and *NOT* the server). GpsGate retrieves coordinates and then outputs that information to the "browser". This allows client systems to have an attached GPS and our system to show their coordinates. If the GPS were attached to the server then it would be pointless -- it would show the server's location and not the end-user's location. I was originally trying to test for the existence of the URL on the server side (in Java) until I realized that it was always returning false because GpsGate wasn't running on the server. I'm not sure how to solve this problem yet. Quote Link to comment https://forums.phpfreaks.com/topic/237245-dynamically-loading-javascript-files/#findComment-1219295 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.