I'm using:
<span id="nodeName"></span>
in my html, then let jquery do:
$("#nodeName").html("someString");
Then, the console says that:
Uncaught TypeError: Object #<HTMLSpanElement> has no method 'toLowerCase'
After I change the id, it works all right. So, is there any reserved id?
I'm using:
<span id="nodeName"></span>
in my html, then let jquery do:
$("#nodeName").html("someString");
Then, the console says that:
Uncaught TypeError: Object #<HTMLSpanElement> has no method 'toLowerCase'
After I change the id, it works all right. So, is there any reserved id?
Share Improve this question asked Jun 26, 2013 at 19:41 YukiYuki 1631 silver badge8 bronze badges 8-
6
It isn't reserved, but using it can have odd side effects in some browsers because
nodeName
is also a property on nodes in javascript, and giving an element an id will (in those specific browsers that have this functionality) automatically generate a property on the window and the node's parent for that id. – Kevin B Commented Jun 26, 2013 at 19:42 -
@KevinB But how could it pose a problem as an
id
? – Ian Commented Jun 26, 2013 at 19:44 - @Ian just selecting the element is enough to cause the error jsfiddle/6HWPr/1 – Kevin B Commented Jun 26, 2013 at 19:46
- 3 heck you don't even have to select it. jsfiddle/6HWPr/2 – Kevin B Commented Jun 26, 2013 at 19:47
-
@KevinB I understand that, I believe the OP and you that it's causing a problem, I'm just wondering why. FYI - while having an element with a specific
id
sets a property onwindow
, it doesn't set a property on its parent node. You might be thinking of setting aname
– Ian Commented Jun 26, 2013 at 19:48
2 Answers
Reset to default 16No, almost any string is a valid ID. And this only happens when you include jQuery (a 1.xx version, not a 2.xx one).
More details :
- the code works, as in "it changes the innerHTML"
- as soon as you include jQuery, even if you don't use it, you have an error in
acceptData
, when the dom is ready, but after the callback you passed to$(document).ready
was executed.
It's a jQuery bug. Why it happens seems to be due to window.nodeName
being defined to this element (which doesn't have a toLowerCase method as it's an element) by the fact the element with this id exists. It seems to be OK in jQuery 2.02.
It is failing in the following function:
acceptData: function( elem ) {
// Do not set data on non-element because it will not be cleared (#8335).
if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
return false;
}
var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
// nodes accept data unless otherwise specified; rejection can be conditional
return !noData || noData !== true && elem.getAttribute("classid") === noData;
}
Specifically on the call elem.nodeName.toLowerCase()
, when elem === window
. This gets called when you include jQuery in the page, even if you never select that element in your Javascript.
The reason is that jQuery does a check to see which elements can handle data-attributes
once jQuery is ready. During that check it calls the acceptData function on the window
element.
This in the most recent versions of jQuery 1, since version 1.8.0 and up to and including the latest 1.10.1. The bug seems to have been introduced by the following change in jQuery 1.8:
$(element).data(“events”): In version 1.6, jQuery separated its internal data from the user’s data to prevent name collisions. However, some people were using the internal undocumented “events” data structure so we made it possible to still retrieve that via .data(). This is now removed in 1.8, but you can still get to the events data for debugging purposes via $._data(element, "events"). Note that this is not a supported public interface; the actual data structures may change inpatibly from version to version.
The window is passed into jQuery._data
as cur
on line 2939 in version 1.8.0, in order to check for the internal "events" data on the window object. This happens when jQuery triggers the $(document).ready
$(window).ready
events. Since window is not a DOM node acceptData shouldn't be called on window at all.
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
I created a bug report