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() { >> >> >>>> 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 > > > > -- Ariel Flesler http://flesler.blogspot.com --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---