Showing Off Some Code!
Posted by Kevin Tran on 2020-04-18
mustationObserver
I had to finish up what I was working on yesterday, I literally was thinking about it as I was falling asleep last night. So with a bunch of free time throughout the day I paced myself and I first refactored the component into a class component so that I had access to lifecycle methods (this application isn't on the latest version of react so so hooks). Once I did that I implemented the code I had in the setTimeout into the componentDidUpdate. Once I did this it was kind of working, I was able to successfully clone the dom element I needed to and have it added and removed when it needed to be. The only issue was that on render the component was updating three times so I had three badge elements in my header, whoops.
But I ended up getting it to work correctly after a few little tweaks. below you'll see the code I wrote and a little walkthrough.
Step 1
I first had to watch for changes on the parent element to know when the child entered and left the dom, if I tried listening to the child element it would break the code because the child didn't always exist.
componentDidUpdate(){
const targetNode = document.getElementById('live-chat-launch')
Step 2
Here I kept track of a state counter to alleviate the issue of the next bit of code running three times and causing three cloned badges to appear.
const { count } = this.state
if (targetNode && count < 1) {
Step 3
Here is where I update the count, clone the element, and append the clone where it needs to be in the dom, while also setting a new ID for the clone to be able to style it differently if needed.
const config = { childList: true }
this.setState({...this.state, count: count + 1})
const callback = (mutationsList, observer) => {
const badge = document.getElementById('w-live-chat-badge')
for (let mutation of mutationsList) {
if (mutation.type === 'childList' && badge) {
const copy = badge.cloneNode()
copy.setAttribute('id', 'New-Badge')
document.getElementById('NotificationToggles').appendChild(copy)
} else {
document.getElementById('New-Badge').remove()
}
}
}
const observer = new MutationObserver(callback)
observer.observe(targetNode, config)
}
}
As of right now, it seems to be working correctly but I'll update once I get feedback!