Finding Elements not attached to Document - javascript

in short
Elements created by createElement and/or createElementNS aren't attached the the main document object at the time of creation, so I can't use document.getElementById to find them until they are attached to the main DOM tree.
Is there an efficient way to 'get' nodes that are off the main DOM tree?
to elaborate:
I'm writing code to generate SVG diagrams dynamically and I can't embed them into the main document until a later point in time. The diagrams are reasonably complicated and I have various functions that each design a portion of the diagram. Each of these functions needs to be able to find the right element of the main SVG object in order to put the elements in the right order. It would be perfect if I could call getElementById from the main SVG node, but I can't since it's not a document.
So I'm stuck with parsing the arrays returned by getElementsByTagName and looking for a target id. Alternatively, I can create an invisible div in the main document and attach it to that, but I want my code to be reusable and not bound to a particular HTML page.
Can I have more than one document object? Say a temporary one that's not displayed where I can build my own DOM (like a video buffer)

Related

Should I detach elements from the DOM while I apply many styles to them?

I'm concerned about performance and best practices.
So I'm building graphical UI and learned that I shouldn't call jQuery.append() a gazillion times when creating many small elements. So I got that covered by document.createDocumentFragment(). I'm adding elements to that, then once done, I insert the fragment to the DOM (with appendChild),
Then, in another pass I calculate where each element should be. Everything is absolutely positioned and will receive x and y values via CSS transform. Unfortunately, for these calculations I need the elements in the DOM since some of them contan random length text, and I need to measure widht/height. Otherwise I would perform step 3 on the document fragment directly, before it's even inserted into the DOM.
In the final pass I apply the calculated styles over everything with jQuery.css() (will likely replace with setAttribute instead of jQuery) as part of a loop (many calls to that, unfortunately - every element has different x/y). Should I detach the container that holds all my elements while I apply the styles, then reattach it to the DOM?
Due to lack of interest I decided to test it myself. Pulling an element of 700+ articles (15000 nodes), applying various CSS on the majority of them, then putting the element back into the page was actually slower by 50%. Let the browser do its job by only showing the results of changed attributes when Layout is needed.
I read the advice somewhere to remove the element from the DOM while working on it. While this could be true when appending elements to it, this does not hold true for style manipulations.

SVG D3 : Is it possible to drag a line with the help of a marker at the end? [duplicate]

I create a simple path in SVG, and use the mark-end attribute for creating an arrow line. Then I bind the click event to the path.
I found the click event was not triggered while I click on the marker area. How to fix this issue?
According to the spec, this should be considered a given.
11.6.4 Details on how markers are rendered
[...]
The rendering effect of a marker is as if the contents of the referenced ‘marker’ element were deeply cloned into a separate non-exposed DOM tree for each instance of the marker. Because the cloned DOM tree is non-exposed, the SVG DOM does not show the cloned instance of the marker.
When a pointer event occurs, hit-testing will be performed by traversing the SVG's DOM tree, thus leaving out any shadow DOM trees, which are non-exposed. That's why there is no chance for marker instances to ever become a target of pointer events.
For clarification it might be interesting to note, that the same holds true when it comes to styling marker instances via CSS rules, which is not feasible. Only the original marker elements, i.e. the declaring <marker> elements, are stylable using CSS, whereas the cloned instances referenced via properties marker-start, marker-mid, or marker-end are not accessible and therefore not individually stylable.
CSS2 selectors can be applied to the original (i.e., referenced) elements because they are part of the formal document structure. CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree because its contents are not part of the formal document structure.

Determine the character index of DOM element inside its owner document's html?

Primarily, I need to convert selection ranges to indices in the source HTML. I was thinking there's a couple ways to do it manually, but is there a built in way to do it?
Some ideas:
Clone the document. Remove the element and its subsequent siblings, and remove all the subsequent siblings of each of its ancestors. Then you just get the document HTML and get its length. o_O
render the tags, text, etc to HTML myself, walking down the DOM tree. Also o_O
The performance could be improved by caching results. Then, if an ancestor already knows its position, it's a bit faster to compute the childs. But then maintaining the cache is another thing.
What about adding a unique ID or class to it and then search for that in the whole document string?

Use javascript to draw a single DOM element in two places

I'm using jQueryUI to create a large table of sortable cards, each of which is composed of a large tree of nested div tags with styling using CSS. When I drag a card under certain conditions, I want to create a slightly transparent "clone" of the card that hovers just to the right of the "real" card while dragging, but I don't want to actually duplicate all of the HTML in order to accomplish this visual effect.
So, is it possible to use javascript to draw the same DOM element on a webpage in two different places without actually duplicating the HTML?
Thanks to anyone who answers.
Each DOM element is either not connected to DOM at all or connected to one specific parent. You cannot display same element in two different places. Attaching to a new parent will just move element from old one.
You can either use cloneNode (take care to attach new event handlers to it, as they are not cloned) or make at JS factory that produces some "template" elements and attach each of them to different parents.

Javascript DOM tree duplicate for manipulation

Since the DOM tree of a page is active and always reflected in the browser, what is the best way to modify this DOM tree for some purpose without affecting the actual rendered tree ? Let's say my purpose is to swap certain children nodes and see how similar the DOM tree still remains.
Is creating a duplicate tree the only solution ? If it is, is there a function to do this ? Or do I need to write my own function to create a duplicate copy of the tree. I won't need all the attributes of the element object, so I can create a simpler object with a few attributes that point to the siblings and children.
You can use document.cloneNode(true), or the same method on another node. cloneNode clones any node, and the true means it should be recursive (deep). Obviously, this could have a significant performance cost on a large page.
If you are willing to use jQuery:
var clone = $("selectorForSomeElement(s)").clone();
clone now is a copy of the element structure.
You can then work off of clone to do whatever experimenting you like.
Maybe consider one the many great JavaScript librarys out there, e.g. jQuery. These allow you to easily copy parts of or even the whole DOM of an document and have that stored appart from the DOM.
If you need to roll your own solution, a good point to start is Resig's post on document fragments: http://ejohn.org/blog/dom-documentfragments/.
Good luck.

Categories

Resources