/    Sign up×
Community /Pin to ProfileBookmark

Reliably move all elements (with event handlers) from one element to another?

Hey guys,

I’m using Shadow DOM to create a custom widget, and I’ve run into what I can only assume is some janky cross-browser shenanigans. The widget is a button that shows/hides the custom component’s inner HTML on click/Enter key. So the code looks something like:

“`html
<my-button>
<!– arbitrary HTML here, this gets copied to a DIV –>
</my-button>
“`

But it seems different browsers have different ideas about how many children the custom element has. On Firefox it works great, but on Chrome and Edge it only copies the first element (???!!!???!!!?). I’ve tried all kinds of crazy strategies, for-loops and while-loops and importNode and cloneNode and innerHTML and others. At the moment, here’s my Firefox-only “”solution”:

“`js
class myClass extends HTMLElement {
connectedCallback() {
while(this.children.length > 0) {
this.div.appendChild(this.children[0]);
}
}
}
“`

My best guess is either there is some place that’s better for this (the constructor maybe?) or maybe this is some kind of race condition where it renders one, then the browser’s “this-is-a-shadow-Dom-thing” engine kicks in and forces children.length to be 0 when it’s not… lol idk, one of those logic-defying things that makes me love programming in C. 😆

to post a comment
JavaScript

4 Comments(s)

Copy linkTweet thisAlerts:
@SempervivumJun 16.2021 — Did you try cloneNode with parameter true?

https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
Copy linkTweet thisAlerts:
@mfoxauthorJun 16.2021 — @Sempervivum#1633043 Yeah, but the same problem seems to persist. Since this morning, I got it working using this workaround:

``js<i>
</i>/**
* Moves all child elements of the custom tag somewhere else
* @param {HTMLElement} where Where to put them
*/
moveChildren(where) {
var t = this, wait = setInterval(function(){
if (t.childElementCount == 0) {
clearInterval(wait);
return;
}
where.appendChild(t.firstElementChild);
}, 10);
}<i>
</i>
``


This kind of suggests that connectedCallback may be getting called before all of the children have loaded. So maybe it's a difference in the order browsers load stuff under the hood (cuz now it's working on all browsers that support Web Components). Thanks for the suggestion tho! :)
Copy linkTweet thisAlerts:
@Momin5465Jun 17.2021 — hope there aren,t any gingerberad or eggnog restritions
Copy linkTweet thisAlerts:
@Momin5465Jun 17.2021 — @Sempervivum#1633043

hope there aren,t any gingerberad or eggnog restritions
×

Success!

Help @mfox spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.23,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...