Although DOM elements can be used like normal JavaScript objects, I'd avoid attaching JavaScript other than handlers. The problem is when they form circular references circular references. In browser garbage collectors, they won't collect garbage if something still references them. If you accidentally form circular references, this will lead to memory leaks (unfreed memory)
jQuery avoids this by creating objects in an internal cache jQuery avoids this by creating objects in an internal cache and assigns an ID to the element. That way, you are assigning a primitive to the element, not an object. This is how jQuery collects and manages event handlers, data attributes, and others.
So a general tip is: What is from JavaScript, stays in JavaScript. (And not cross over to the DOM)
In jQuery's case, the functions are not actually attached to the element. That's the purpose of the "jQuery object". In a gist, a jQuery object is just an array-like object (let's call it "pseudo-array" from this point on), that contains DOM elements. The prototype of the jQuery object is where the functions live. These functions operate on each value in the collection.
Executing a function in a jQuery object is not like this:
someElement.doSomething();
But rather, something like this:
collectionOfStuff.forEach(function(DOMElement,i,arr){ //do something for each in the collection });
Widget
in your code is some function that manufactures "widget templates" which are used to bind to your elements. Rather than havingWidget
return the template, why not makeWidget
your namespace. You can then create a function that attaches to the namespace.It would be synonymous to doing
jQuery.fn.extend(function(){...})
//define widget Widget.defineWidget('Page',function(){ //local stuff, aka "private" var privateVar = 'foo'; function privateFn(){...} //anything attached to `this` is "public" //we will execute this function, providing an object as `this` this.publicVar = 'bar'; this.publicFn = function(){...} }); //access widget var reference = Widget.Page(bindingTarget);
defineWidget
define a creator function into the namespace that uses the widget definition to build instances, something like:Widget.defineWidget = function(name,fn){ //store wigetCache[name] = fn; //attach to namespace Widget[name] = function(){ //BaseClass could be some constructor with prototype containing //all functions that widgets should have var instance = new BaseClass(); //run the instance through the definition to attach the internals return fn.call(instance); } }
Although DOM elements can be used like normal JavaScript objects, I'd avoid attaching JavaScript other than handlers. The problem is when they form circular references. In browser garbage collectors, they won't collect garbage if something still references them. If you accidentally form circular references, this will lead to memory leaks (unfreed memory)
jQuery avoids this by creating objects in an internal cache and assigns an ID to the element. That way, you are assigning a primitive to the element, not an object. This is how jQuery collects and manages event handlers, data attributes, and others.
So a general tip is: What is from JavaScript, stays in JavaScript. (And not cross over to the DOM)
In jQuery's case, the functions are not actually attached to the element. That's the purpose of the "jQuery object". In a gist, a jQuery object is just an array-like object (let's call it "pseudo-array" from this point on), that contains DOM elements. The prototype of the jQuery object is where the functions live. These functions operate on each value in the collection.
Executing a function in a jQuery object is not like this:
someElement.doSomething();
But rather, something like this:
collectionOfStuff.forEach(function(DOMElement,i,arr){ //do something for each in the collection });
Widget
in your code is some function that manufactures "widget templates" which are used to bind to your elements. Rather than havingWidget
return the template, why not makeWidget
your namespace. You can then create a function that attaches to the namespace.It would be synonymous to doing
jQuery.fn.extend(function(){...})
//define widget Widget.defineWidget('Page',function(){ //local stuff, aka "private" var privateVar = 'foo'; function privateFn(){...} //anything attached to `this` is "public" //we will execute this function, providing an object as `this` this.publicVar = 'bar'; this.publicFn = function(){...} }); //access widget var reference = Widget.Page(bindingTarget);
defineWidget
define a creator function into the namespace that uses the widget definition to build instances, something like:Widget.defineWidget = function(name,fn){ //store wigetCache[name] = fn; //attach to namespace Widget[name] = function(){ //BaseClass could be some constructor with prototype containing //all functions that widgets should have var instance = new BaseClass(); //run the instance through the definition to attach the internals return fn.call(instance); } }
Although DOM elements can be used like normal JavaScript objects, I'd avoid attaching JavaScript other than handlers. The problem is when they form circular references. In browser garbage collectors, they won't collect garbage if something still references them. If you accidentally form circular references, this will lead to memory leaks (unfreed memory)
jQuery avoids this by creating objects in an internal cache and assigns an ID to the element. That way, you are assigning a primitive to the element, not an object. This is how jQuery collects and manages event handlers, data attributes, and others.
So a general tip is: What is from JavaScript, stays in JavaScript. (And not cross over to the DOM)
In jQuery's case, the functions are not actually attached to the element. That's the purpose of the "jQuery object". In a gist, a jQuery object is just an array-like object (let's call it "pseudo-array" from this point on), that contains DOM elements. The prototype of the jQuery object is where the functions live. These functions operate on each value in the collection.
Executing a function in a jQuery object is not like this:
someElement.doSomething();
But rather, something like this:
collectionOfStuff.forEach(function(DOMElement,i,arr){ //do something for each in the collection });
Widget
in your code is some function that manufactures "widget templates" which are used to bind to your elements. Rather than havingWidget
return the template, why not makeWidget
your namespace. You can then create a function that attaches to the namespace.It would be synonymous to doing
jQuery.fn.extend(function(){...})
//define widget Widget.defineWidget('Page',function(){ //local stuff, aka "private" var privateVar = 'foo'; function privateFn(){...} //anything attached to `this` is "public" //we will execute this function, providing an object as `this` this.publicVar = 'bar'; this.publicFn = function(){...} }); //access widget var reference = Widget.Page(bindingTarget);
defineWidget
define a creator function into the namespace that uses the widget definition to build instances, something like:Widget.defineWidget = function(name,fn){ //store wigetCache[name] = fn; //attach to namespace Widget[name] = function(){ //BaseClass could be some constructor with prototype containing //all functions that widgets should have var instance = new BaseClass(); //run the instance through the definition to attach the internals return fn.call(instance); } }
Although DOM elements can be used like normal JavaScript objects, I'd avoid attaching JavaScript other than handlers. The problem is when they form circular references. In browser garbage collectors, they won't collect garbage if something still references them. If you accidentally form circular references, this will lead to memory leaks (unfreed memory)
jQuery avoids this by creating objects in an internal cache and assigns an ID to the element. That way, you are assigning a primitive to the element, not an object. This is how jQuery collects and manages event handlers, data attributes, and others.
So a general tip is: What is from JavaScript, stays in JavaScript. (And not cross over to the DOM)
In jQuery's case, the functions are not actually attached to the element. That's the purpose of the "jQuery object". In a gist, a jQuery object is just an array-like object (let's call it "pseudo-array" from this point on), that contains DOM elements. The prototype of the jQuery object is where the functions live. These functions operate on each value in the collection.
Executing a function in a jQuery object is not like this:
someElement.doSomething();
But rather, something like this:
collectionOfStuff.forEach(function(DOMElement,i,arr){ //do something for each in the collection });
Widget
in your code is some function that manufactures "widget templates" which are used to bind to your elements. Rather than havingWidget
return the template, why not makeWidget
your namespace. You can then create a function that attaches to the namespace.It would be synonymous to doing
jQuery.fn.extend(function(){...})
//define widget Widget.defineWidget('Page',function(){ //local stuff, aka "private" var privateVar = 'foo'; function privateFn(){...} //anything attached to `this` is "public" //we will execute this function, providing an object as `this` this.publicVar = 'bar'; this.publicFn = function(){...} }); //access widget var reference = Widget.Page(bindingTarget);
defineWidget
define a creator function into the namespace that uses the widget definition to build instances, something like:Widget.defineWidget = function(name,fn){ //store wigetCache[name] = fn; //attach to namespace Widget[name] = function(){ //BaseClass could be some constructor with prototype containing //all functions that widgets should have var instance = new BaseClass(); //run the instance through the definition to attach the internals return fn.call(instance); } }