I ended up using the method in SVGEdit suggested by DuoPixel. It uses other SVGEdit method defined in svgcanvas.js so it's not really meant as a standalone. Here's a working link to DuoPixel method suggested in the comments:

With the specific implementation in case the link changes:

// This method sends back an array or a NodeList full of elements that
// intersect the multi-select rubber-band-box on the current_layer only.
// Since the only browser that supports the SVG DOM getIntersectionList is Opera,
// we need to provide an implementation here. We brute-force it for now.
// Reference:
// Firefox does not implement getIntersectionList(), see
// Webkit does not implement getIntersectionList(), see
var getIntersectionList = this.getIntersectionList = function(rect) {
if (rubberBox == null) { return null; }
var parent = current_group || getCurrentDrawing().getCurrentLayer();
if(!curBBoxes.length) {
// Cache all bboxes
curBBoxes = getVisibleElementsAndBBoxes(parent);
var resultList = null;
try {
resultList = parent.getIntersectionList(rect, null);
} catch(e) { }
if (resultList == null || typeof(resultList.item) != "function") {
resultList = [];
if(!rect) {
var rubberBBox = rubberBox.getBBox();
var bb = {};
for(var o in rubberBBox) {
bb[o] = rubberBBox[o] / current_zoom;
rubberBBox = bb;
} else {
var rubberBBox = rect;
var i = curBBoxes.length;
while (i--) {
if(!rubberBBox.width || !rubberBBox.width) continue;
if (svgedit.math.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) {
// addToSelection expects an array, but it's ok to pass a NodeList
// because using square-bracket notation is allowed:
return resultList;


Preface: @Duopixel's comment on your original post is great -- I didn't know that method exists. However, it looks like it only supports a rectangular region per the MSDN docs, whereas it seems more intuitive to have a circle around the mouse.

A couple of other techniques:

  1. Use an invisible, thick stroke that "expands" your element, if you're not otherwise using the stroke for styling, or draw a transparent line/shape on top of the element that is some amount larger. Listen to the 'click' event for these elements.

  2. Do a pairwise comparison of every element with that of the mouse's click radius. I made an example here: I only implemented circles because they were easy -- you'd need to add the geometry for rectangles.

Related Query