Test the truthiness of the valued returned by .attr(), and make sure that el is actually a jQuery object.
getElementId: function(el) { if (!el.jquery) { el = $(el); } if(!el.attr('id')) { el.attr('id',"anim-"+Math.random().toString().substr(2)); } // alert(el.attr('id')); return el.attr('id'); },
Depending on the attribute you're trying to retrieve, .attr() may return undefined or "".
Other recommended cleanup:
getElementId: function(el) { if (!el.jquery) { el = $(el); } var id = el.attr('id'); if(!id) { // make sure this ID hasn't actually been used before! do { id = "anim-"+Math.random().toString().substr(2); } while (!$('#' + id).length); el.attr('id', id); } return id; },
You really need to make sure that you're not assigning an ID to that element which has already been used before. The above function does this. A simpler way to accomplish the same thing is to use an incrementing counter stored somewhere outside of the scope of the function:
__idCounter__: 1, getElementId: function(el) { if (!el.jquery) { el = $(el); } var id = el.attr('id'); if(!id) { id = "anim-" + (this.__idCounter__++); el.attr('id', id); } return id; },
Last edit (I promise)
There seems to be confusion about what .attr() returns when an element does not have the attribute requested. After running some tests, it looks like .attr() returns:
- the empty string for at least
id and class (perhaps other HTML4-spec attributes as well; didn't test) undefined for other attributes not defined by the spec
Output from my tests:
<div id="myID"/> id: myID <div id="myID"/> class: <div id="myID"/> data-attr: undefined <div id="myID"/> asdf: undefined <div class="myClass"/> id: <div class="myClass"/> class: myClass <div class="myClass"/> data-attr: undefined <div class="myClass"/> asdf: undefined <div data-attr="myAttr"/> id: <div data-attr="myAttr"/> class: <div data-attr="myAttr"/> data-attr: myAttr <div data-attr="myAttr"/> asdf: undefined <div asdf="myNonSpecAttr"/> id: <div asdf="myNonSpecAttr"/> class: <div asdf="myNonSpecAttr"/> data-attr: undefined <div asdf="myNonSpecAttr"/> asdf: myNonSpecAttr
tl;dr
Just test the truthiness of the value returned by .attr(), since that treats undefined and "" (the empty string) the same:
if (somejQueryElt.attr('someAttr')) { // it definitely has the attribute } else { // it definitely does not have the attribute }
el.attr('id', 'anim...does it execute? you can try stepping through your code in firebug and see if it breaks on that statementela jQuery object? If it is not then.attrwont work for you.if((typeof(el.attr('id'))).toString() == 'undefined') {typeofis an operator, not a function, so the parentheses are unnecessary in this case.typeofalways returns a string, to thetoString()call is completely unnecessary. And, since you know you're always comparing strings to strings, you should be using===(the strict equality operator), not==(the type-coercing equality operator).==when I have a specific purpose for type coercion (usually when I'm doingx == null). My point is that it doesn't make sense to say you shouldn't use the type-coercing operator when there will be no type-coercion. In such a case, it makes no difference which you use.