PDA

View Full Version : YAHOO.ext.Element.get



jclawson
6 Feb 2007, 4:11 PM
In our code (formerly based on prototype), we do a lot of dynamic DOM creation. Many times we do not attach the created elements to the document until later in the code. This presents a problem when working with your library as your functions depend on YAHOO.ext.Element.get which requires the element to be appended to the document. I cannot think of any reason why you require this. I have created a patch that will allow the passing of an element that is not appended to the document. From my testing, it breaks nothing. I tried to maintain backwards compatibility. My changes are marked with comments.

I would appreciate it if you would test it, and if it meets your expectations, commit it to subversion. Thanks!



YAHOO.ext.Element.get = function(){
var doc = document;
var docEl;
var E = YAHOO.ext.Element;
var D = YAHOO.util.Dom;

return function(el){
if(!el){ return null; }
if(el instanceof E){
if(el != docEl){
/*
* if getElementById is ull, use el.dom
*/
var domElem = doc.getElementById(el.id);
el.dom = (domElem)?domElem:el.dom;
E.cache[el.id] = el;
}
return el;
}else if(el.isComposite){
return el;
}else if(el instanceof Array){
return E.select(el);
}else if(el == doc){

if(!docEl){
var f = function(){};
f.prototype = E.prototype;
docEl = new f();
docEl.dom = doc;
}
return docEl;
}
var key = el;
if(typeof el != 'string'){
D.generateId(el, 'elgen-');
key = el.id;
}
var element = E.cache[key];
if(!element){
/*
* pass el instead of key. YAHOO.ext.Element will handle it. You don't need to pass it key.
*/
element = new E(el);
if(!element.dom) return null;
E.cache[key] = element;
}else{
element.dom = doc.getElementById(key);
}
return element;
};
}();

jack.slocum
6 Feb 2007, 6:31 PM
Actually in the latest dev code this function has been completely refactored (huge speed boost on most calls). One big boost came from reorganizing the conditionals based on the order that they are most likely to be found. "Element not in the document" in no longer a problem. Here's the code, it does depend on a few shorthands (ithe whole Element class is wrapped in a closure). D = YAHOO.util.Dom, El = Ext.Element, doc = document, docEl is an empty variable.




/**
* Static method to retreive Element objects. Uses simple caching to consistently return the same object.
* Automatically fixes if an object was recreated with the same id via AJAX or DOM.
* @param {String/HTMLElement/Element} el The id of the node, a DOM Node or an existing Element.
* @return {Element} The Element object
* @static
*/
El.get = function(el){
var ex, elm, id;
if(!el){ return null; }
if(typeof el == 'string'){ // element id
if(!(elm = doc.getElementById(el))){
return null;
}
if(ex = El.cache[el]){
ex.dom = elm;
}else{
ex = El.cache[el] = new El(elm);
}
return ex;
}else if(el.tagName){ // dom element
if(!(id = el.id)){
id = D.generateId(el);
}
if(ex = El.cache[id]){
ex.dom = el;
}else{
ex = El.cache[id] = new El(el);
}
return ex;
}else if(el instanceof El){
if(el != docEl){
el.dom = doc.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid,
// catch case where it hasn't been appended
El.cache[el.id] = el; // in case it was created directly with Element(), let's cache it
}
return el;
}else if(el.isComposite){
return el;
}else if(el instanceof Array){
return El.select(el);
}else if(el == doc){
// create a bogus element object representing the document object
if(!docEl){
var f = function(){};
f.prototype = El.prototype;
docEl = new f();
docEl.dom = doc;
}
return docEl;
}
return null;
};

jclawson
7 Feb 2007, 10:04 AM
Perfect! That is exactly the functionality I needed! :D Thanks!