Question

I would like to have the "same" HTML element rendered in multiple places on the page. This element is scripted/animated and the various renderings need to stay in sync.

The solutions I have considered include:

  1. Put copies of the element in multiple places and update all of them. This is what I am trying to avoid.
  2. Put copies of the element in multiple places. Update one of the copies, and use mutation events to capture those changes and replay them against the other copies. Seems like a lot of work.
  3. Use shadow DOM. I had high hopes for this alternative, which initially seems to be possible, using "insertion points", which allow a DOM subtree over here to be virtually placed in a DOM subtree over there.

I have not tested this last alternative, which is available in Chrome 25 . The W3C spec says:

One case that deserves special consideration is the situation when an insertion point is a child node of another shadow host...The effect of a node being distributed into more than one insertion point is called reprojection.

But then...

Despite being distributed to more than one insertion point during reprojection, a node is still only rendered once, because of the constraints under which the reprojection occurs: since the insertion points are only subject to reprojection when they are children of a shadow host, they are never rendered. Instead the shadow tree is rendered in their place.

Does it seem likely that shadow DOM likely to do what I want and is worth testing, or is there something other recommended approach?

Was it helpful?

Solution

Shadow DOM reprojection does not do what you want.

I’m part of the team implementing Shadow DOM in Chrome. The commentary in the spec is right—content in Shadow DOM is rendered once at most once.

Here are a couple of ideas which might be useful, depending on what exactly you’re trying to achieve:

Firefox has an experimental feature where an element can be used as a background. This is hooked up in CSS using background: -moz-element(#foo); where foo is the ID of the element you want to copy. The image is “live”; changes to the element are reflected everywhere it is used as a background.

Using -moz-element has a few potential downsides: It is only implemented in some versions of Firefox; it is experimental, which means the feature might change or go away at some point; and the copy is not interactive—you can’t click on buttons in there, hovering over the copy does not trigger :hover styles, and so on.

If you want all of the copies to be interactive, use Mutation Observers. There is a library called Mutation Summary which wraps Mutation Observers and includes an example Chrome extension which mirrors an entire page. You could adapt it to mirror a subtree of DOM. Depending on your application you could also use Mutation Observers to mirror the DOM bi-directionally.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top