Log only clicked button in console, attach event to all buttons (new or existing)

I want only the clicked button to be logged in the console, regardless of whether the button is newly injected or already present in the page.

I want the click event to be attached to all the buttons that are present, and only the button that was actually clicked should be logged in the console.

However on clicking the said button, all instances(all injected buutons) present in the page gets logged on console.

Below code is a part of content.js of a chrome extension under development—

const observer = new MutationObserver(function (mutationsList) {
	mutationsList.forEach(mutation => {
		if (mutation.type === "childList") {
			const toolBarDivs = document.querySelectorAll('div[aria-label*="replies"]')

			toolBarDivs.forEach(toolBarDiv => {
				if (!toolBarDiv.dataset.siblingInjected) {
					try {
						const newDiv = document.createElement("div")
						newDiv.classList.add("css-175oi2r", "r-18u37iz", "r-1h0z5md", "r-13awgt0", "copy-paste-button")
						newDiv.innerHTML = `
                          <button aria-label="Copypaste" role="button" class="css-175oi2r r-1777fci r-bt1l66 r-bztko3 r-lrvibr r-1loqt21 r-1ny4l3l" data-testid="copypaste" type="button" data-copy-paste-button-added="true">
                              <svg fill="#000000" height="18px" width="18px" viewBox="0 0 502 502">
                                  <path d="M81.5,174H247c5.523,0,10-4.477,10-10s-4.477-10-10-10H81.5c-5.523,0-10,4.477-10,10S75.977,174,81.5,174z"></path>
                                  <path d="M306.5,220h-225c-5.523,0-10,4.477-10,10s4.477,10,10,10h225c5.523,0,10-4.477,10-10S312.023,220,306.5,220z"></path>
                                  <path d="M306.5,286h-225c-5.523,0-10,4.477-10,10s4.477,10,10,10h225c5.523,0,10-4.477,10-10S312.023,286,306.5,286z"></path>
                                  <path d="M306.5,352h-225c-5.523,0-10,4.477-10,10s4.477,10,10,10h225c5.523,0,10-4.477,10-10S312.023,352,306.5,352z"></path>
                                  <path d="M306.5,154h-22c-5.523,0-10,4.477-10,10s4.477,10,10,10h22c5.523,0,10-4.477,10-10S312.023,154,306.5,154z"></path>
                                  <path d="M481,379.417h-47.713c-2.364,0-4.287-1.923-4.287-4.287v-9.98c0-9.858-5.885-18.666-14.993-22.438c-9.108-3.772-19.497-1.706-26.468,5.265L377,358.516V103c0-2.652-1.054-5.196-2.929-7.071l-93-93C279.196,1.054,276.652,0,274,0H21c-5.523,0-10,4.477-10,10v482c0,5.523,4.477,10,10,10h346c5.523,0,10-4.477,10-10v-7.681l10.539,10.539c4.658,4.657,10.841,7.125,17.149,7.125c3.133,0,6.297-0.609,9.319-1.861c9.107-3.772,14.993-12.58,14.993-22.438v-9.98c0-2.364,1.923-4.287,4.287-4.287H481c5.523,0,10-4.477,10-10v-64C491,383.894,486.523,379.417,481,379.417z M284,34.142L342.858,93H284V34.142z M357,482H31V20h233v83c0,5.523,4.477,10,10,10h83v265.516l-35.831,35.83c-1.406,1.407-2.351,3.189-2.735,5.111c-0.128,0.641-0.194,1.297-0.194,1.96c0,2.652,1.054,5.196,2.929,7.071L357,464.319V482z M471,443.417h-37.713c-13.392,0-24.287,10.895-24.287,24.287v9.98c0,2.493-1.658,3.551-2.646,3.961c-0.99,0.409-2.911,0.833-4.672-0.93l-59.299-59.298l59.298-59.298c1.763-1.762,3.684-1.338,4.672-0.929c0.988,0.409,2.646,1.468,2.646,3.96v9.98c0,13.392,10.895,24.287,24.287,24.287H471V443.417z"></path>
                              </svg>
                          </button>
                      `
						toolBarDiv.insertBefore(newDiv, toolBarDiv.children[3] || null)
						toolBarDiv.dataset.siblingInjected = "true"
					} catch (error) {
						console.error("Error injecting button:", error)
					}
				}
			})
		}
	})

	const allButtons = document.querySelectorAll('button[data-testid="copypaste"]')

	allButtons.forEach(button => {
		button.addEventListener("click", event => {
			console.log("Button clicked:", event.target)
		})
	})
})

observer.observe(document.body, { childList: true, subtree: true })

I tried this(outside mutation observer logic) also didn’t works—

document.body.addEventListener('click', function(event) {
  if (event.target.tagName === 'BUTTON' && event.target.hasAttribute('data-testid') && event.target.getAttribute('data-testid') === 'copypaste') {
    console.log('Button clicked:', event.target);
  }
});

Mutating the DOM child lists inside a mutation observer listening for childlists sounds like a disaster waiting to happen. Just saying.

Also your observer will be attaching an event to all buttons each time it fires. So if you have 1 button in your page with an event, and your observer fires 4 times, the button will have 5 events attached to its click… are you sure you’re seeing “all instances” being put on the page, or the same button firing all X of its events?

addEventListener doesnt replace, it stacks.

(PS: Happy Joining Anniversary)

1 Like

Thanks Sir, so I have to reapproach the whole logic, please suggest what should I do or what JS logic should I fillow. Or what would you have done if you would have in my place?

so you mean same single button (not multiple buttons are firing) when I click once is firing number of times the mutations is working?

Well I cant speak for your mutation observer, because i dont know why you’re observing mutations.

For the event, i would do what you tried to do in post 2. Outside of all the observer stuff, delegate an event to the body (or the non-dynamic container of the buttons) listening for a click.

I would suggest you Inspect one of your buttons in the developer tool, and look at the number of Click events assigned to it.

(You may want to uncheck the “Ancestors” option, since you know the events in question are specifically being bound to the buttons)

After unchecking, the screen goes blank — https://screenrec.com/share/SvNPrweWfj

Your screenshot tells me you’re looking at the path, not the button.
image

1 Like


This means no even is getting attached.

if you check ancestors again, how many appear?

1 Like

Z E R O

so there’s nothing bound to the button, but the button does something?

Are… you… sure?

When event listeners are added to buttons inside the MutationObserver code, the buttons at least respond to clicks. However, when the event listeners are placed outside the MutationObserver, even though the buttons exist in the DOM and are visible on the page, they fail to respond to clicks.

oh okay, so you’ve moved the code to the body now? What’s your current code for event binding?

1 Like

currently clicked event code is out of mutation logic:

Strange as soon as I remove svg under the insertable button, it results in just one click. Inside button element if you nest any elemnt such as div, svg click fails. but not when like this—