Ariel, while looking at the specifications and searching in the MDC site I found that "compareDocumentPosition()" can test for detached nodes.
https://developer.mozilla.org/en/DOM/Node.compareDocumentPosition DOCUMENT_POSITION_DISCONNECTED = 0x01; // the one we need DOCUMENT_POSITION_PRECEDING = 0x02; DOCUMENT_POSITION_FOLLOWING = 0x04; DOCUMENT_POSITION_CONTAINS = 0x08; DOCUMENT_POSITION_IS_CONTAINED = 0x10; so: a.compareDocumentPosition(b) & 1 will tell us if the node is connected or disconnected from the DOM tree. Isn't this what we were after on W3C browsers ? -- Diego On 3 Dic, 19:48, "Ariel Flesler" <[EMAIL PROTECTED]> wrote: > For an element from any other document. > > Examples: > - IFrames > - XML > - Other documents > > On Wed, Dec 3, 2008 at 4:44 PM, Diogo Baeder <[EMAIL PROTECTED]> wrote: > > Alright, but what is the difference between "document" and > > "el.ownerDocument"? I tested: > > > alert(document.getElementsByTagName('body')[0].ownerDocument == document); > > > And it returns true... which are the cases where this may return false? > > > Diogo > > > On Wed, Dec 3, 2008 at 4:27 PM, Ariel Flesler <[EMAIL PROTECTED]> wrote: > > >> That's what I was sort of suggesting, el.ownerDocument.documentElement, > >> that is. > > >> As someone said (don't recall and don't wanna read up), good browsers > >> (w3) do set ownerDocument to null when the node is outside any > >> document. > > >> Assuming that's true: > > >> $.fn.inDOM = function(){ > >> var elem = this[0], > >> doc = el && el.ownerDocument && el.ownerDocument.documentElement; > > >> return !!doc && (doc.contains ? > >> doc.contains(el) > >> : !!(doc.compareDocumentPosition(el) & 16) > >> ); > >> }; > > >> On Wed, Dec 3, 2008 at 4:15 PM, ricardobeat <[EMAIL PROTECTED]> wrote: > > >> > Why not simplify? > > >> > $.fn.inDOM = function(){ > >> > var el=this[0]; > >> > if (!el) return false; > >> > var doc = el.ownerDocument.documentElement; > >> > return (doc.contains) > >> > ? doc.contains(el) > >> > : !!(doc.compareDocumentPosition(el) & 16); > >> > }; > > >> > 36ms vs 12ms for Diogo's 'inDOM3Optimized', but keeps it compatible > >> > with other 'document' contexts. That's 1000 iterations, I don't see > >> > anyone having thousands of elements that he doesn't know if are in the > >> > DOM or not. It works in all target browsers, so the parentNode > >> > fallback is not needed. > > >> > Ariel, is there any situation where a node has no ownerDocument/ > >> > documentElement property? > > >> > - ricardo > > >> > On Dec 3, 11:21 am, "Ariel Flesler" <[EMAIL PROTECTED]> wrote: > >> >> Those functions relying on $('html') wouldn't work for xml or some > >> >> other special kind of document (namespaced tagnames?). > > >> >> I think it is indeed better to rely on the documentElement of the > >> >> ownerDocument (if the latter exists else just false). > > >> >> On Wed, Dec 3, 2008 at 12:40 AM, Diogo Baeder <[EMAIL PROTECTED]> > >> >> wrote: > > >> >> > Diego, if I can recall, I already tested el.ownerDocument and, in > >> >> > IE6, > >> >> > it always returned true in Boolean test, even if the element was > >> >> > removed. > > >> >> > The "bifurcated" implementation was tested in all browsers with > >> >> > success > >> >> > (except for FF2, which I didn't have in my machine at the time): FF3, > >> >> > IE6, IE7, Safari 3.1.2 and Opera 9.62. > > >> >> > About the method name, it's a good point... ok by me to change it to > >> >> > "isOrphan" and invert the return from the past implementation... > > >> >> > I also updated the implementations and testing in the benchmark, > >> >> > putting > >> >> > a "return false" if no element is false (correcting, thus, the bugs > >> >> > of > >> >> > when the elements were removed from DOM) and setting $('#level10') to > >> >> > a > >> >> > variable (in the "deep-level" testing), thus eliminating the need for > >> >> > a > >> >> > new traversal in every loop iteration. Here they are: > > >> >> > ----- IMPLEMENTATIONS: > > >> >> > $.fn.inDOM1 = function() { > >> >> > return !!$(this).parents('html').length; > >> >> > }; > > >> >> > $.fn.inDOM2 = function() { > >> >> > var el = this[0]; > >> >> > if (!el) return false; > >> >> > while (el.parentNode) el = el.parentNode; > >> >> > return el.nodeType == 9; > >> >> > }; > > >> >> > $.fn.inDOM3 = function() { > >> >> > var el = this[0]; > >> >> > if (!el) return false; > >> >> > var html = $('html').get(0); > >> >> > return html.contains ? > >> >> > html != el && html.contains(el) : > >> >> > !!(html.compareDocumentPosition(el) & 16); > >> >> > }; > > >> >> > var docEl = document.documentElement; > >> >> > $.fn.inDOM3Optimized = docEl.contains ? > >> >> > function() { > >> >> > var el = this[0]; > >> >> > if (!el) return false; > >> >> > return docEl != el && docEl.contains(el); > >> >> > } : > >> >> > function() { > >> >> > var el = this[0]; > >> >> > if (!el) return false; > >> >> > return !!(docEl.compareDocumentPosition(el) & 16); > >> >> > }; > > >> >> > --- PERFORMANCE RESULTS: > > >> >> > ===== inDOM1: parents("html") ===== > >> >> > start: 1228270728766 ms > >> >> > end: 1228270729258 ms > >> >> > difference: 492 ms > > >> >> > ===== inDOM2: parentNode ===== > >> >> > start: 1228270729274 ms > >> >> > end: 1228270729437 ms > >> >> > difference: 163 ms > > >> >> > ===== inDOM3: html.contains() ===== > >> >> > start: 1228270729450 ms > >> >> > end: 1228270729808 ms > >> >> > difference: 358 ms > > >> >> > ===== inDOM3Optimized: html.contains() ===== > >> >> > start: 1228270729821 ms > >> >> > end: 1228270729911 ms > >> >> > difference: 90 ms > > >> >> > ===== inDOM2: traversing 10 levels ===== > >> >> > start: 1228270729924 ms > >> >> > end: 1228270730161 ms > >> >> > difference: 237 ms > > >> >> > ===== inDOM3Optimized: traversing 10 levels ===== > >> >> > start: 1228270730173 ms > >> >> > end: 1228270730184 ms > >> >> > difference: 11 ms > > >> >> > ===== inDOM2: after removal ===== > >> >> > start: 1228270730198 ms > >> >> > end: 1228270730382 ms > >> >> > difference: 184 ms > > >> >> > ===== inDOM3Optimized: after removal ===== > >> >> > start: 1228270730395 ms > >> >> > end: 1228270730405 ms > >> >> > difference: 10 ms > > >> >> > Note: inDOM2 is the impl. using parentNode, and inDOM3 is the one > >> >> > using > >> >> > special methods ("bifurcated code"). > >> >> > Note 2: the speed in "inDOM3Optimized" changed a lot just because I > >> >> > setted $('level10') to a variable before all the tests. This > >> >> > strengthens > >> >> > the performance reason to favor the "bifurcated code" implementation. > >> >> > ;-) > > >> >> > If everybody agrees with the method name change (to "isOrphan"), > >> >> > which > >> >> > is OK by me, I can do it in the benchmarks to keep consistency with a > >> >> > possible future version of jQuery. > > >> >> > Diogo > > >> >> > Diego Perini escreveu: > >> >> >> John, > >> >> >> I believe there is an error, probably you meant: > > >> >> >> $.fn.inDOM = document.documentElement.contains ? > >> >> >> function() { > >> >> >> var el = this[0], root = el.ownerDocument.documentElement; > >> >> >> return root !== el && root.contains(el); > >> >> >> } : > >> >> >> function() { > >> >> >> var el = this[0]; > >> >> >> return !! > >> >> >> (el.ownerDocument.documentElement.compareDocumentPosition(el) & 16); > >> >> >> }; > > >> >> >> or if you prefer in the declaration "var el = > >> >> >> this[0].ownerDocument". > > >> >> >> As I already said, the native methods are the fastest, no doubt, but > >> >> >> the standalone version is still to be considered alone or combined. > > >> >> >> However, I believe we should test the following minor implications > >> >> >> if > >> >> >> deemed important: > > >> >> >> - all target browser implementing one of the two native methods ? > >> >> >> - all target browser having an "element.ownerDocument" ? > > >> >> >> And for the function name I see "isOrphan/isOrphanNode" more > >> >> >> adequate > >> >> >> since if we can do: > > >> >> >> var node = document.createElement("div"); > > >> >> >> that node seems to me is already in the DOM, explicitly the one > >> >> >> attached to "document" through the "ownerDocument" DOM property, the > >> >> >> fact is that the node is not yet attached to the rendered tree, thus > >> >> >> a > >> >> >> node without a parent ancestor, that may be a simple element a > >> >> >> DOMFragment or even a new Image() instance. > > >> >> >> I further suggest to split this and implement "contains" or such in > >> >> >> jQuery on the track of what you wrote about this on your blog and > >> >> >> move > >> >> >> the conditional there so this will simply remain: > > >> >> >> function() { > >> >> >> var el = this[0], root = el.ownerDocument.documentElement; > >> >> >> return root !== el && root.contains(el); > >> >> >> } > > >> >> >> no branches there. They will be in the generic "contains" method > >> >> >> (very > >> >> >> useful...). In that method you could add the parent traversal as > >> >> >> fall > >> >> >> back. > > >> >> >> In this way you add more functionalities to jQuery use the fastest > >> >> >> in > >> >> >> this OP and keep the code size down to the minimum still covering > >> >> >> cross-browser 100%. > > >> >> >> -- > >> >> >> Diego > > >> >> >> On 2 Dic, 17:25, "John Resig" <[EMAIL PROTECTED]> wrote: > > >> >> >>> Why not just tweak this implementation to be relative? That way you > >> >> >>> still get performance but also allow it to work across frames, etc. > > >> >> >>> $.fn.inDOM = document.documentElement.contains ? > >> >> >>> function() { > >> >> >>> var el = this[0], doc = el.documentElement; > >> >> >>> return doc !== el && doc.contains(el); > >> >> >>> } : > >> >> >>> function() { > >> >> >>> var el = this[0]; > >> >> >>> return !!(el.documentElement.compareDocumentPosition(el) > >> >> >>> & 16); > >> >> >>> }; > > >> >> >>> --John > > >> >> >>> On Tue, Dec 2, 2008 at 9:41 AM, Ariel Flesler <[EMAIL PROTECTED]> > >> >> >>> wrote: > > >> >> >>>> I'd just save it as a local var > > >> >> >>>> var html = document.documentElement; > >> >> >>>> $.fn.inDOM = html.contains ? > >> >> >>>> function() { > > ... > > leggi tutto --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/jquery-dev?hl=en -~----------~----~----~----~------~----~------~--~---
