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:
>>>>>>>
>>>>>>>> ricardo,
>>>>>>>>
>>>>>>>> On 1 Dic, 05:35, ricardobeat <[EMAIL PROTECTED]> wrote:
>>>>>>>>
>>>>>>>>> I always miss the obvious stuff :)
>>>>>>>>>
>>>>>>>>> I ended up with this, it's a lot faster than Diogo's code but still
>>>>>>>>> requires you to traverse the document all the way up. John Resig's
>>>>>>>>> 'contains' function is at least twice faster in FF though, so it
>>>>>>>>> seems
>>>>>>>>> like the perfect solution.
>>>>>>>>>
>>>>>>>>> $.fn.inDOM = function(){
>>>>>>>>>    var el = this[0];
>>>>>>>>>    while (el.parentNode) el = el.parentNode;
>>>>>>>>>    return el == this[0].ownerDocument;
>>>>>>>>>
>>>>>>>>> };
>>>>>>>>>
>>>>>>>> To make it less dependent:
>>>>>>>>
>>>>>>>> $.fn.inDOM = function(){
>>>>>>>>   var el = this[0];
>>>>>>>>   while (el.parentNode) el = el.parentNode;
>>>>>>>>    return el.nodeType == 9;
>>>>>>>> };
>>>>>>>>
>>>>>>>> now you can also pass elements present in other DOM contexts.
>>>>>>>>
>>>>>>>> Don't know if this modifies the intended usage, this will most
>>>>>>>> generally tell if the element is an orphan (not attached to any
>>>>>>>> document).
>>>>>>>>
>>>>>>>> To account for both usages, it will be necessary to pass context
>>>>>>>> information (an extra parameter to specify the desired context).
>>>>>>>>
>>>>>>>> --
>>>>>>>> Diego
>>>>>>>>
>>>>>>>>> - ricardo
>>>>>>>>>
>>>>>>>>> On 30 nov, 19:43, "Ariel Flesler" <[EMAIL PROTECTED]> wrote:
>>>>>>>>>
>>>>>>>>>> Yeah, parentNode is not good enough.
>>>>>>>>>>
>>>>>>>>>> On Sun, Nov 30, 2008 at 4:35 PM, ricardobeat
>>>>>>>>>> <[EMAIL PROTECTED]>
>>>>>>>>>>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> It seems the ownerDocument is set for the created element even
>>>>>>>>>>> if
>>>>>>>>>>>
>>>>>>>> it's
>>>>>>>>
>>>>>>>>>>> not in the DOM, it's the document where jQuery was loaded in. A
>>>>>>>>>>>
>>>>>>>> simple
>>>>>>>>
>>>>>>>>>>> check for parentNode or offsetParent would do:
>>>>>>>>>>>
>>>>>>>>>>> $.fn.inDOM = function(){
>>>>>>>>>>>     return !!this.parentNode; //boolean
>>>>>>>>>>> });
>>>>>>>>>>>
>>>>>>>>>>> parentNode returns faster for elements in the DOM, while
>>>>>>>>>>> offsetParent
>>>>>>>>>>> returns faster for elements not in the DOM (in FF3 at least).
>>>>>>>>>>>
>>>>>>>>>>> Hope I'm not missing anything. It surely would need a better
>>>>>>>>>>> name :]
>>>>>>>>>>>
>>>>>>>>>>> cheers,
>>>>>>>>>>> - ricardo
>>>>>>>>>>> On 29 nov, 14:46, Ariel Flesler <[EMAIL PROTECTED]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> 'body' should be replaced by 'html'.
>>>>>>>>>>>>
>>>>>>>>>>>> Maybe we can make it faster by consulting expandos like
>>>>>>>>>>>> ownerDocument ?
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Ariel Fleslerhttp://flesler.blogspot.com
>>>>>>>>>>>>
>>>>>>>>>>>> On Nov 27, 12:52 am, diogobaeder <[EMAIL PROTECTED]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Hi there,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'm new here (and in jQuery), but even though I'd like to
>>>>>>>>>>>>> propose
>>>>>>>>>>>>>
>>>>>>>> some
>>>>>>>>
>>>>>>>>>>>>> simple but usefull method to the jQuery object (at core.js)
>>>>>>>>>>>>> to
>>>>>>>>>>>>>
>>>>>>>> tell
>>>>>>>>
>>>>>>>>>>>>> the API user if an element exists in the document. I've tried
>>>>>>>>>>>>> to
>>>>>>>>>>>>>
>>>>>>>> build
>>>>>>>>
>>>>>>>>>>>>> one as follows:
>>>>>>>>>>>>>
>>>>>>>>>>>>> [CODE]
>>>>>>>>>>>>> (function($) {
>>>>>>>>>>>>>
>>>>>>>>>>>>>     $.fn.inDOM = function() {
>>>>>>>>>>>>>         return !!this.parents('body').length;
>>>>>>>>>>>>>     };
>>>>>>>>>>>>>
>>>>>>>>>>>>> })(jQuery);
>>>>>>>>>>>>>
>>>>>>>>>>>>> jQuery(document).ready(function(){
>>>>>>>>>>>>>     var jEl = $('.someExistingClass');
>>>>>>>>>>>>>
>>>>>>>>>>>>>     // Should be in DOM
>>>>>>>>>>>>>     console.debug(jEl.inDOM());
>>>>>>>>>>>>>
>>>>>>>>>>>>>     // Removing the element
>>>>>>>>>>>>>     jEl.remove();
>>>>>>>>>>>>>
>>>>>>>>>>>>>     // Should NOT be in DOM
>>>>>>>>>>>>>     console.debug(jEl.inDOM());});
>>>>>>>>>>>>>
>>>>>>>>>>>>> [/CODE]
>>>>>>>>>>>>>
>>>>>>>>>>>>> So, if the client sets a variable as a jQuery object, and at
>>>>>>>>>>>>> some
>>>>>>>>>>>>> point of the code the DOM element within it can be removed,
>>>>>>>>>>>>> he/she
>>>>>>>>>>>>>
>>>>>>>> can
>>>>>>>>
>>>>>>>>>>>>> test if it really was. OK, I know it sounds unsignificant,
>>>>>>>>>>>>> but I
>>>>>>>>>>>>>
>>>>>>>> think
>>>>>>>>
>>>>>>>>>>>>> it would still be usefull.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks!
>>>>>>>>>>>>>
>>>>>>>>>>>>> Diogo Baeder
>>>>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Ariel Fleslerhttp://flesler.blogspot.com
>>>>>>>>>>
>>>>>>> --
>>>>>>> Diogo Baederhttp://www.diogobaeder.com.br
>>>>>>>
>>>>> --
>>>>> Diogo Baeder
>>>>> http://www.diogobaeder.com.br
>>>>>
>>>> --
>>>> Ariel Flesler
>>>> http://flesler.blogspot.com
>>>>
>> >
>>
>>
>
> >
>



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

Reply via email to