To make any element attractive, not just interactive content, you must set the tabindex attribute .
In your example, this would be:
<div id='myeditdiv' contenteditable='true'> <span class='foo_cl' tabindex="-1">FOO<span class='bar_cl' tabindex="-1">bar</span</span> </div>
Note: a negative tabindex makes the element oriented , but not tabbable, because the tabbing method will start at 0 using an absolute value ( spec ).
Now in jQuery you can delegate the focus event to these elements:
$('[contenteditable]').on('focus', '*', function(e){ e.stopPropagation(); console.log(this); });
- jsFiddle-
As a side note, the jQuery UI has a pseudo-selector :focusable . If you want to dynamically set the tabindex attribute tabindex inactive elements, you can use:
$('[contenteditable]').find(':not(:focusable)').attr('tabindex', -1);
- jsFiddle (including jQuery user interface) -
If you don't want to include jQuery UI to get a :focusable pseudo-selector, you can create your own custom selector:
//include IIFE if not already including jQuery UI (function () { function focusable(element, isTabIndexNotNaN) { var map, mapName, img, nodeName = element.nodeName.toLowerCase(); if ("area" === nodeName) { map = element.parentNode; mapName = map.name; if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") { return false; } img = $("img[usemap='#" + mapName + "']")[0]; return !!img && $(img).is(':visible'); } return (/^(input|select|textarea|button|object)$/.test(nodeName) ? !element.disabled : "a" === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && // the element and all of its ancestors must be visible $(element).is(':visible'); } $.extend($.expr[":"], { focusable: function (element) { return focusable(element, !isNaN($.attr(element, "tabindex"))); } }); })();
- jsFiddle-