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() { > >> >>>> var el = this[0]; > >> >>>> return html != el && $.html.contains(el); > >> >>>> } : > >> >>>> function() { > >> >>>> var el = this[0]; > >> >>>> return !!(html.compareDocumentPosition(el) & 16); > >> >>>> }; > >> > >> >>>> Does this work reliably on any browser ? > >> >>>> Note that his doesn't work for any document that is not THE > document. > >> > >> >>>> I think a simple traversal (going up) would do. I'm sorry to spoil > all > >> >>>> the researching but no one said this function will be used > everywhere > >> >>>> and it needs to be as fast as possible. First it most be effective, > >> >>>> then efficient. > >> > >> >>>> On Tue, Dec 2, 2008 at 12:07 PM, Diogo Baeder < > [EMAIL PROTECTED]> wrote: > >> > >> >>>>> Thanks! > >> > >> >>>>> Guys, the last proposal gave me about 140ms ~ 150ms within 1000 > method > >> >>>>> calls, but here's something that gave me about 80ms ~ 90ms: > >> > >> >>>>> $.htmlEl = $('html').get(0); > >> >>>>> $.fn.inDOM = $.htmlEl.contains ? > >> >>>>> function() { > >> >>>>> var el = this[0]; > >> >>>>> return $.htmlEl != el && $.htmlEl.contains(el); > >> >>>>> } : > >> >>>>> function() { > >> >>>>> var el = this[0]; > >> >>>>> return !!($.htmlEl.compareDocumentPosition(el) & 16); > >> >>>>> }; > >> > >> >>>>> What do you think of it? A little bit more of coding, but > considerably > >> >>>>> faster... despite someone would rarely make so much calls to this > method, I > >> >>>>> think... > >> > >> >>>>> Diogo > >> > >> >>>>> On Mon, Dec 1, 2008 at 10:36 PM, Diego Perini < > [EMAIL PROTECTED]> > >> >>>>> wrote: > >> > >> >>>>>> Diogo, > >> > >> >>>>>> On 1 Dic, 21:56, "Diogo Baeder" <[EMAIL PROTECTED]> wrote: > >> > >> >>>>>>> Thank you, guys... I tried the last method as > implemented/adapted by > >> >>>>>>> Diego, > >> >>>>>>> and it works! :-) > >> > >> >>>>>>> Unfortunately, neither "contains" nor "compareDocumentPosition" > are > >> >>>>>>> being > >> >>>>>>> recognized as methods for the "document" node in IE6 or 7, as > you can > >> >>>>>>> test > >> >>>>>>> yourselves: > >> > >> >>>>>>> alert(document.contains); > >> >>>>>>> alert(window.contains); > >> >>>>>>> alert(document.compareDocumentPosition); > >> >>>>>>> alert(window.compareDocumentPosition); > >> > >> >>>>>>> Any ideas why these didn't work for me? > >> > >> >>>>>> The Microsoft "contains" method does not exists for the document > >> >>>>>> object (at least in the docs). Maybe because it is not an element > >> >>>>>> (nodeType == 1). > >> > >> >>>>>> Firefox and Opera implement the "compareDocumentPosition" method, > also > >> >>>>>> they made it a method of the "document" itself. > >> > >> >>>>>> Opera implements both "compareDocumentPosition" and "contains", > Safari > >> >>>>>> only has "contains" again not on the "document". > >> > >> >>>>>> The conclusion is that the implementations of > "compareDocumentPosition > >> >>>>>> ()" and "contains()" disagree on this specific fact. > >> > >> >>>>>> At this point, given the messed up implementations, better being > >> >>>>>> independent from them both and go for the traversal. > >> > >> >>>>>> It is also much shorter and really cross-browser... > >> > >> >>>>>> -- > >> >>>>>> Diego > >> > >> >>>>>>> Diogo > >> > >> >>>>>>> On Mon, Dec 1, 2008 at 10:58 AM, Diego Perini > >> >>>>>>> <[EMAIL PROTECTED]>wrote: > >> > >> ... > >> > >> read more ยป > > > > > > > > > -- > Ariel Flesler > http://flesler.blogspot.com > > > > -- Diogo Baeder http://www.diogobaeder.com.br --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to jquery-dev@googlegroups.com 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 -~----------~----~----~----~------~----~------~--~---