Hi people. Thomas DeWeese: > Thanks for raising this. This is an issue I had been considering > addressing for a _long_ time. It is unfortunately not a really > trivial thing to 'do right'. There are three things that jump out > at me as being potentially problematic with your current > implementation.
Yes, I've had some code to do id hashing sitting around for a couple of weeks too, but only just was reminded of it by Fritz' post. > 1) getElementById I believe works on a subtree of the document. > So unless the 'globally' registered element is a child of the > element getElementById is called on the result should be null. Well you can only call getElementById on a Document, so it should find any element with the right id anywhere in the document tree. *checks* Ah I see, the SVGSVGElement.getElementById (which I hadn't noticed existed) restricts to the subtree. > 2) Adding/removing elements/subtree's. Someone can add a whole > subtree to a document and all those nodes need to have their > id's added, also when a subtree is removed there id's need to > be removed (which might reveal a hidden duplicate id...). Yes, I found I had to track whether certain elements were in the document tree or not so that the ids would only be hashed when the subtree was inserted. > 3) For things like document fragments or simply disconnected > node tree's they should probably have an independent id space. Hmm, document fragments was one that I'd dismissed since there is no getElementById method on a DocumentFragment. > The first is fairly easily solved by simply ensuring that > 'this' (in getElementById) is an ancestor of the element found in the > hash table. If it isn't then return null. But yeah, that would work. > The second is trickier. A few ideas, detecting that an old > element has been removed from the tree should be fairly easy > given the 'parent' check above (it will fail). Although it points out > that the hash entries should be soft references so that elements that > were once part of the tree with an id can still be GC'ed. There > is a significant issue about what should happen if the hashed node > isn't listed (see next section). Or you could just make sure that the references are removed from the hash table when the subtree is removed from the document tree. > Adding nodes, the simple thing would be to just walk the new > subtree and add it's nodes to the parent document. One issue will > be the handling of duplicate Id's. They may be duplicates because > the old element was recently removed, or they may be duplicates > because for the next instant both nodes will be in the tree (they > add then remove for example). In the second case the "hard ass" > response is throw an illegal state exception... This will not win > very many friends however it is probably the 'correct' thing to do. > If you don't do this, then you run the risk that when you remove a > subtree there were element's that had the same id that were shadowed > which would be a pain to track. I have a hash table of linked lists holding all of the elements with that id, so that when a duplicate id element is removed, leaving a single element with the id, getElementById will work again. > Another option would be to be slightly lazy about it, so when > subtree's are added mark them as 'dirty', when someone asks for an id > - check the hash table if it is present and still part of the document > great return it. Otherwise start walking the 'dirty' subtree's adding > id's as you go, until you get to the one you want (or return null). > This is nice from the point of view of not making 'add' overly > expensive. This is not a bad idea, but I think won't increase performance for cases like this: <g id="g1"/> <g id="g2"/> <g id="g3"/> <g id="g4"/> ... and your script looks up each of these IDs in order. Cameron -- Cameron McCormack | Web: http://mcc.id.au/ | ICQ: 26955922 --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]