Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you avoid losing focus on a contenteditable element when a user clicks outside that element?

I want to prevent a contentEditable area from losing focus if a click is made outside that area. Some sample HTML looks like this:

<div id="content">
    <p>Hello</p>
</div>
<div id="clickThis">
    <p>If you click on this or anywhere for that matter after focusing on Hello, you lose your focus on Hello</p>
</div>

Sample Javascript looks as follows:

$(document).ready(function()
{
    $('#content')[0].contentEditable=true;

    $('#clickThis').bind('click',function(e)
    {
        console.log(window.getSelection().getRangeAt(0).startContainer);
        e.preventDefault();
    });
});

When you click on the #clickThis div or anywhere outside the #content div, you lose focus on the #content div even if you call the click event's preventDefault function.

In addition, the range changes the moment the click event is fired, so I can't just return to the previous range after the click has occurred. Is there a way to maintain the cursor position and focus after a click occurs?

jsFiddle: http://jsfiddle.net/VivekVish/FKDhe/4/

like image 980
Deets McGeets Avatar asked Sep 12 '11 19:09

Deets McGeets


2 Answers

Putting Juan's question into an answer, instead of using the click event, you have to use the mousedown event as follows:

$(document).ready(function()
{
    $('#content')[0].contentEditable=true;

    $('#clickThis').bind('mousedown',function(e)
    {
        console.log(window.getSelection().getRangeAt(0).startContainer);
        e.preventDefault();
    });
});

You can see it working here:

http://jsfiddle.net/FKDhe/7/

like image 148
Deets McGeets Avatar answered Oct 22 '22 13:10

Deets McGeets


The answer is to add event.preventDefault() to the mouseDown event.

const button = document.getElementById('boldFormat')

button.addEventListener('mousedown', (event) => {
  event.preventDefault() // prevent loss of focus
  document.execCommand('bold', false)
})

The problem occurred because the you are listening to the click event which causes the contentEditable element to lose focus; regardless of whether you run preventDefault or not.

like image 1
Jack Avatar answered Oct 22 '22 13:10

Jack