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
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---