Placeholder in contenteditable - focus event issue

2019-01-21 00:50发布

I have been trying to ask this before, without any luck of explaining/proving a working example where the bug happens. So here is another try:

I’m trying to replicate a placeholder effect on a contenteditable DIV. The core concept is simple:

<div contenteditable><em>Edit me</em></div>

<script>
$('div').focus(function() {
    $(this).empty();
});
</script>

This can sometomes work, but if the placeholder contains HTML, or if there some other processing being made, the editable DIV’s text caret is being removed, and the user must re-click the editable DIV to be able to start typing (even if it’s still in focus):

Example: http://jsfiddle.net/hHLXr/6/

I can’t use a focus trigger in the handler, since it will create an event loop. So I need a way to re-set the caret cursor in the editable DIV, or in some other way re-focus.

10条回答
在下西门庆
2楼-- · 2019-01-21 00:54

This is not exact solution of your problem ..

in summernote options set

airMode:true

placeholder works in this way.

查看更多
干净又极端
3楼-- · 2019-01-21 01:00

Here is a CSS only solution augmenting some of the other answers:-

<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
    [contentEditable=true]:empty:not(:focus)::before{
        content:attr(data-ph)
    }
</style>

EDIT: Here is my snippet on codepen -> http://codepen.io/mrmoje/pen/lkLez

EDIT2: Be advised, this method doesn't work 100% for multi-line applications due to residual <br> elements being present in the div after performing a select-all-cut or select-all-delete on all lines. Credits:- @vsync
Backspace seems to work fine (at least on webkit/blink)

查看更多
该账号已被封号
4楼-- · 2019-01-21 01:02

I found that the best way to do this is to use the placeholder attribute like usual and add a few lines of CSS.

HTML

<div contenteditable placeholder="I am a placeholder"></div>

CSS

[contenteditable][placeholder]:empty:before {
    content: attr(placeholder);
    color: #bababa;
}

Note: the CSS :empty selector only works if there is literally nothing in-between the opening and closing tag. This includes new lines, tabs, empty space, etc.

Codepen

查看更多
兄弟一词,经得起流年.
5楼-- · 2019-01-21 01:02

Here's the fix that I used.

<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
    var target = $(this);
    window.setTimeout(function() { target.empty(); }, 10);
});
</script>

I developed a jQuery plug-in for this. Take a look https://github.com/phitha/editableDiv

查看更多
爷的心禁止访问
6楼-- · 2019-01-21 01:07

just use css pseudo-classes.

span.spanclass:empty:before {content:"placeholder";}
查看更多
仙女界的扛把子
7楼-- · 2019-01-21 01:11
var curText = 'Edit me';
$('div').focusin(function() {
    if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
        $(this).empty();
    }
}).focusout(function() {
    if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
        $(this).html('<em>' + curText + '</em>');
    }
});
查看更多
登录 后发表回答