enguerran
enguerran

Reputation: 3291

set focus on contenteditable div with jquery

Could you help me understand why the div that is retrieving the focus put the cursor on first char on Firefox and IE 10 (but not on chrome)?

Here is the javascript code:

$('div').on('click', function(e) {
    $(this).html($(this).text());
});

Here is the jsfiddle with the whole context.

[EDIT] Could someone tell me why the cursor is going to the beginning of the sentence?

Upvotes: 1

Views: 2457

Answers (2)

Onur Yıldırım
Onur Yıldırım

Reputation: 33634

Behavior Difference:

That's because Chrome does not think that the content is changed when you pass the same/exact content but FF/IE do not care whether the content is the same or not; if anything is passed, they think it's modified. Different browser engines do not always act the same way.

$('div').on('click', function(e) {
    $(this).html($(this).text()); // here you pass the same (previous) content
});

To see if the browser (Chrome or FF) interprets this as "content changed"; you can listen to the DOMSubtreeModified event. This will not fire on Chrome but it will fire on FF.

$('div').on('DOMSubtreeModified', function(e) {
    console.log('content changed');
});

Now, if you "really" change the content by passing a "new" value; Chrome will act the same as FF too. For example, try this:

$('div').on('click', function(e) {
    $(this).html($(this).text() + "new content"); // passing different content each time
});

Now, you'll see that the DOMSubtreeModified event is fired.

Why the cursor moves to the beginning:

That's because; when the user clicks the div, he/she actually sets the cursor to some position/index. Then you immediately change the full content; so the position/index is no more available while the content is being replaced. The only valid position is 0 (the beginning index) at that time.

This does not happen in Chrome if the same content is passed bec. (as mentioned before); Chrome does not replace the content if it's the same as the previous content. So the cursor index is never changed. But if you do pass a different content; it will also move the cursor to the beginning.


Here is the fiddle for the DOMSubtreeModified test.

Upvotes: 3

KaraokeStu
KaraokeStu

Reputation: 768

The issue is that IE and Firefox have a different implementation of contentEditable. This means that, when clicked, they select the first element within the editable area.

You can get around this issue by using some code like the following:

var char = 3, sel; // character at which to place caret
content.focus();
if (document.selection) {
  sel = document.selection.createRange();
  sel.moveStart('character', char);
  sel.select();
}
else {
   sel = window.getSelection();
  sel.collapse(content.firstChild, char);
}

However, what I'd recommend is using something like TinyMCE or CKEditor or a JQuery/JQueryUI editor to get the desired effect.

Plus, you get the nice formatting tools too!

Upvotes: 0

Related Questions