This question (to which I added a bounty) is related and gives the context and motivations (my GPLv3 MELT monitor on github; I added at last some README to it).
I am only interested in recent HTML5 compliant browsers (on GNU/Linux), e.g. Firefox 38 at least (and preferably 42) or Chrome 46 (on Debian/Sid desktop, x86-64)
So, suppose I have in my HTML5 page
<div id='myeditdiv' contenteditable='true'>
<span class='foo_cl'>FOO<span class='bar_cl'>bar</span></span>
</div>
(actually the HTML is generated, and so is the DOM; I'm currently generating on the server side some javascript which constructs the DOM; of course I can change the generators!)
And I am clicking so that the focus come between the two OO
. How can I get the DOM element of foo_cl
, preferably with Jquery.
Same question when focusing between ar
. I want the bar_cl
span.
Of course, $(':focus')
don't work. It gives the div
FWIW, it is commit 9109ae5b3d168f1 of the MELT monitor.
PS. See my (november 26th 2015) addenda to this question. Probably contenteditable
is not useful to me, but tabindex
surely is useful!
To make any element focusable, not only interactive content ones, you have to set tabindex attribute.
In your sample, it 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: negative tabindex
makes element focusable but not tabbable because using tabbing method would start at 0
using absolute value (spec).
Now in jQuery, you could delegate focus
event to these elements:
$('[contenteditable]').on('focus', '*', function(e){
e.stopPropagation();
console.log(this);
});
-jsFiddle-
As a side note, jQuery UI has a :focusable
pseudo selector. If you wish to dynamically set tabindex
attribute to not focusable elements, you could use:
$('[contenteditable]').find(':not(:focusable)').attr('tabindex', -1);
-jsFiddle (including jQuery UI)-
If you don't want to include jQuery UI just to get :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-
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With