1

I am trying to add keyboard even listeners (keyup, keydown) to a <div> that contains an <svg> element. This post notes that SVGs do not currently support handling keyboard events, so I tried adding the events to a <div> surrounding the <svg>. But it doesn't appear to work either. (fiddle) Nor does adding event handlers to a group of all the elements contained in the SVG.

Is this possible to do? Am I doing something wrong?

(I don't want to assign the event handlers to the body or window because I have a text input forms on a different part of the page.)

Community
  • 1
  • 1
ropeladder
  • 1,103
  • 11
  • 24

2 Answers2

3

you can attach keyboard event to svg elements . but along with keyboard down you have to attach focus event without attaching focus it does't works.

var chart = d3.select("#chart")
    .style("fill", "red")
    .style("height", '600px')

var svg = chart.append("svg")
    .attr("width", 500)
    .attr("height", 300);

var currentObject = null;

svg.append("circle")
    .attr("class","selectme").attr("id","circle")
    .attr("cx",50).attr("cy",50).attr("r",45)
    .style("fill","lightblue");
svg.append("rect")
    .attr("class","selectme").attr("id","rectangle")
    .attr({"x":10,"y":150,"width":150,"height":100})
    .style("fill","lightgreen");
d3.selectAll(".selectme")
    .on("mouseover", function() {
        d3.select(this).style("stroke","black");
        currentObject = this;
    })
    .on("mouseout", function() {
        d3.select(this).style("stroke","none");
        currentObject = null;
    });

d3.select("svg")
    .on("keydown", function() {
        svg.append("text")
            .attr("x","5")
            .attr("y","130")
            .style("font-size","20px")
        .text("keyCode: " + d3.event.keyCode + " applied to : " + (currentObject===null ? "nothing!" : currentObject.id))  
          .transition().duration(2000)
            .style("font-size","5px")
            .style("fill-opacity",".1")
          .remove();
    }).on("focus", function(){});
Ashish Patel
  • 921
  • 1
  • 10
  • 26
  • It doesn't seem to be working? I've tried adding focus events to the [svg](http://jsfiddle.net/xk3cwgzg/6/) and the [div](http://jsfiddle.net/xk3cwgzg/5/). – ropeladder Aug 30 '16 at 10:41
  • it works for me for svg yes but with div its not. you can refer this one to make it work with div http://stackoverflow.com/a/20126915/5047556 – Ashish Patel Aug 30 '16 at 11:40
  • 1
    Hmm, it seems like the SVG fiddle in my previous comment only works in Chrome, not in Firefox (49 beta). I ended up using the suggestion in the link you posted: setting a toggle using mouseover/mouseout for the SVG element, and adding the `keydown` listeners to the `window` element: `d3.select(window).on('keydown', function(){ if(toggle) keydownAction() }). Thanks for your help. – ropeladder Aug 30 '16 at 13:17
  • You can try adding the following attributes to an svg element: ".attr("focusable","true") .attr("tabindex","0")" These allowed me to focus on different elements in an svg to hang eventListeners on. – Montmorency Jul 02 '20 at 19:52
0

Use the attribute tabindex with the value 0. Example:

<div tabindex="0">...</div>

tabindex=0 makes the div selectable so that, with a focus on it, you can catch key events. According to the documentation, " tabindex="0" means that the element should be focusable in sequential keyboard navigation ". (https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex)

Another source of information: https://stackoverflow.com/a/3149416/9649530

Another solution consists in using contenteditable="true" but this also shows the key sequences you type in the div.

ARno
  • 314
  • 3
  • 14