jQuery事件可正常运行,原生JavaScript事件无法正常工作
Hey there! Let's dig into why your native custom event isn't triggering your D3 listener, even though jQuery events work fine. The most common culprit here relates to event bubbling and element targeting—let's break it down step by step.
1. The #1 Issue: Custom Events Don't Bubble By Default
Unlike jQuery's event system (which enables bubbling by default), the native CustomEvent constructor has bubbles: false as its default setting. Here's the problem in your code:
- You're dispatching the event on
this.element(likely a child element of#container) - But your D3 listener is bound to
#container(the parent)
Since bubbling is disabled, the event can't travel up from this.element to #container, so your D3 code never picks it up.
Fix It: Enable Bubbling in Your Custom Event
Update your CustomEvent creation to explicitly allow bubbling:
var myCustomEvent = new CustomEvent('myEvent', { detail: {data: myData}, bubbles: true, // Critical: lets the event propagate up the DOM cancelable: true // Optional: allows event.preventDefault() if needed }); this.element.dispatchEvent(myCustomEvent);
2. Double-Check Element Targeting
Make sure this.element is either:
- Directly the
#containerelement (so you're dispatching the event right where the listener is bound), or - A descendant of
#container(with bubbling enabled, as above)
If this.element is unrelated to #container (not a child/descendant), even with bubbling, the event won't reach the listener. Test this by temporarily dispatching the event directly on #container:
// Test if the listener works when dispatched directly d3.select('#container').node().dispatchEvent(myCustomEvent);
If this triggers your handler, you know the issue is the relationship between this.element and #container.
3. Verify that Scope in Your D3 Listener
While this won't prevent the event from firing, it can make it seem like nothing's happening if that isn't pointing to your custom object correctly. Instead of relying on a that variable, use an arrow function to preserve the outer context:
// Arrow function preserves the 'this' from the outer scope d3.select('#container').on('myEvent', (event) => { console.log('Custom event received! Data:', event.detail.data); this.foo(/* your arguments here */); });
4. Check for Typos in Event Names
Double-check that the event name you use in CustomEvent (myEvent) matches exactly what you pass to d3.select().on()—native events are case-sensitive, so a typo like myevent or MyEvent would break things.
Quick Recap of the Fixed Code
Here's how your code should look with the key fixes:
// Inside your custom object's prototype function createAndDispatchEvent() { const myData = { /* your data */ }; const myCustomEvent = new CustomEvent('myEvent', { detail: {data: myData}, bubbles: true }); this.element.dispatchEvent(myCustomEvent); } // Your D3 listener setup const myCustomObject = new YourCustomObject(); d3.select('#container').on('myEvent', (event) => { myCustomObject.foo(event.detail.data); });
That should get your native custom event firing with D3 just like it does with jQuery!
内容的提问来源于stack exchange,提问作者tgordon18

