Jump to content

Coexisting with unknown code?


davej

Recommended Posts

Are there a set of known rules that would allow Javascript to coexist peacefully with other Javascript or is that situation so complex that it is impossible to analyze? For example I can see that globals might need to be avoided and using addEventListener() would be required for handlers to prevent any possible conflicts with other event handler assignments.

 

For WordPress there is this discussion... http://codex.wordpress.org/Using_Javascript

...which provides some guidance, but I just don't really understand what they are saying.

 

Link to comment
Share on other sites

One thing I do is to create an object with a name that would be unique and put everything in it so that there's only one possible conflicting global. I guess you could consider that its namespace.

var MyProjectName = {};MyProjectName.global1 = "value1";MyProjectName.method1 = function(param1, param2) {    /* Some code */}

An alternative is to wrap everything in a function wrapper. Anything declared with var or function in it will be global to everything else inside it:

(function() {    var global1 = "value1";    function method1(param1, param2) {        /* Some code */    }})();

addEventListener() and Internet Explorer's attachEvent() are enough to make sure that your event handlers don't overwrite other event handlers.

  • Like 1
Link to comment
Share on other sites

there are numerous design patterns that one can implement in Javascript, the most common of them being the Namespace pattern that Ingolme pointed out. There are others as well. I learned a lot from reading this book.

http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752/ref=pd_sim_b_5

Edited by thescientist
Link to comment
Share on other sites

A related thread: http://w3schools.invisionzone.com/index.php?showtopic=48408

 

I am beginning to look at the patterns here... http://addyosmani.com/resources/essentialjsdesignpatterns/book/

 

--EDIT--

 

I have also now purchased the O'Reilly "Patterns" book.

Edited by davej
Link to comment
Share on other sites

  • 1 month later...

Ok, this will be my new boilerplate file...

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>title</title><style></style><script>window.onerror = function(m, u, l){alert('Javascript Error: '+m+'nURL: '+u+'nLine Number: '+l);return true;}</script><script>var p = {};//project namespacep.init = function() {document.getElementById('btn1').onclick = p.put;}p.put = function() {var txt = document.getElementById('in1').value;document.getElementById('out1').innerHTML = txt;}window.onload = p.init;</script></head><body><input type="text" id="in1"/><input type="button" id="btn1" value="Enter"/><div id="out1"></div></body></html>

For whatever reason the functions must now be expressed in variable form or they don't work.

Link to comment
Share on other sites

Yes, you have to declare the function in that way if it belongs to an object.

 

I'd recommend useing addEventListener rather than .onclick or .onload if you want to avoid overwriting events or having them overwritten by other scripts.

Link to comment
Share on other sites

p.addHandler = function(element,event,funct){if (element.addEventListener){element.addEventListener(event,funct,false);}else if (element.attachEvent){element.attachEvent(event,funct);//IE7,IE8}else{element['on'+event] = funct;if(element=='window' && event=='load'){alert('Your Browser is Obsolete');}}}p.addHandler(window,'load',p.init);
Edited by davej
Link to comment
Share on other sites

Yes, that's pretty much what most people do. jQuery has that all done internally, though, so if you're using jQuery you don't need to worry about cross-browser compatibility.

I'd change the last condition to:

element["on" + event] = funct;
Link to comment
Share on other sites

Oops, yes.

 

I am having some trouble getting interested in jQuery although I'm sure that solving cross-compatibility issues is a significant factor in its popularity.

Link to comment
Share on other sites

that is, in fact, its primary mission. and of course it also has a powerful DOM selector engine.

Edited by thescientist
Link to comment
Share on other sites

So then every time I go down another level I need another object declaration, right?

<script>var p = {};//project namespacep.tools = {};p.tools.clock = {};p.init = function() {p.tools.clock.init();}p.tools.clock.init = function() {var time1 = document.getElementById('time');time1.innerHTML = '';p.tools.clock.storedtime = new Date();p.tools.clock.tick();}[etc...]
Link to comment
Share on other sites

If you're creating new objects then you should define them first as an empty object, if that's what you're asking (or define them with their properties and methods). While on the topic of code that should work with other unknown code though, I would avoid using single-character global variable names. Use global variable names that aren't likely to be used by any other code.

Link to comment
Share on other sites

Yeah, the single letter approach seems iffy, but it certainly is easier to type over and over. I was thinking a search and replace could later be used to change the one letter global to something longer, but I'm not sure how well that might work.

Link to comment
Share on other sites

What I don't like is that the order of the code seems much more restricted using a global object -- as if you are using a single-pass compiler. You have to declare the functions in the order of use or else risk an unreported error condition... or at least that is the way it seems.

Edited by davej
Link to comment
Share on other sites

You can declare functions like you would anywhere else, but they will only be defined in the scope in which you declare them. You can add references to them if you want to make certain functions available on your global object. e.g.:

 

 

function test() {  ...}p.test = test;
Link to comment
Share on other sites

What I've noticed is that while this works...

<script>window.onload = init;function init() {// do something}

...this does not work...

<script>var p = {};//project namespacewindow.onload = p.init;p.init = function() {//do something}

...and while it just refuses to do anything... it doesn't throw errors.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...