Contenteditable with a nested range. Who has the trick?

This question (to which I added generosity) is related and gives context and motives (my GPLv3 MELT monitor on github, I finally added README).

I'm only interested in the latest HTML5 compatible browsers (on GNU / Linux), for example. Firefox 38 at least (and preferably 42) or Chrome 46 (on the Debian / Sid desktop, x86-64)

So, suppose I have HTML5 on my page

<div id='myeditdiv' contenteditable='true'> <span class='foo_cl'>FOO<span class='bar_cl'>bar</span></span> </div> 

(HTML is actually generated as well as DOM, I am currently generating server side javascript that creates the DOM, of course I can change the generators!)

And I press so that the focus is between two OO . How can I get the DOM element from foo_cl , preferably using jQuery.

The same question when focusing between ar . I want bar_cl span.

Of course, $(':focus') does not work. He gives a div

FWIW, this is MELT Monitor Fix 9109ae5b3d168f1 .

PS. See My (November 26 th 2015) additions to this subject . tabindex probably not useful to me, but tabindex probably useful!

+3
source share
1 answer

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-

+1
source

Source: https://habr.com/ru/post/1240728/


All Articles