JohnJ
JohnJ

Reputation: 4823

d3: intercepting keydown events over specific elements

I want to identify key press events which occur over specific D3 elements. The following snippet (JSFiddle here) correctly identifies mousing over individual divs, and global key press events, but does not seem to fire the div-specific key press handler (tested only on Chrome so far). What is the simplest way to either:

  1. identify which div/svg the cursor is over, or
  2. attach a key handler to a specific div/svg

?

_.each(_.range(2), function (i) {
    var svg = d3.select("#plot" + i).append("svg")
        .attr("width", 100)
        .attr("height", 100);

    svg.append("rect")
        .attr("fill", "red")
        .attr("x", 0)
        .attr("y", 0)
        .attr("width", 100)
        .attr("height", 100)
        .on("mouseover", function () { console.log("mouseover", i); })
        .on("keydown", function () { console.log("div key", i); });
});

d3.select("body").on("keydown", function () { console.log("global key"); });

Thanks!

EDIT

As a followup, I suppose I could capture the div ID in the mouseover handler and use that to identify the appropriate div in the global keydown event -- but I'm curious if there is a more elegant or idiomatic solution.

Upvotes: 2

Views: 5143

Answers (2)

wes
wes

Reputation: 972

you can also use d3.event.stopPropagation() to keep events from bubbling up to the body.

Upvotes: 0

Gopherkhan
Gopherkhan

Reputation: 4342

*D'oh. Your edit had exactly this solution. Yup, that's probably the best way to handle it. *

You might need to use the mouseover handler to keep track of the element that is currently focused, and then use the page listener to delegate the event to that node.

something like this:

var focused = null;
svg.append("rect").on("mouseover", function () { focused = this; })

And then in your page-handler:

d3.select("body").on("keydown", function () { d3.select(focused); /* then do something with it here */ });

Upvotes: 3

Related Questions