在contenteditable中的占位符—焦点事件问题

[英]Placeholder in contenteditable - focus event issue


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:

我之前一直在试着问这个问题,没有任何解释/证明bug发生的例子。这是另一个尝试:

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

我试图在contenteditable DIV上复制占位符效应。

<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):

这可以起到一些作用,但是如果占位符包含HTML,或者正在进行其他处理,那么可编辑的DIV的文本插入符号将被删除,并且用户必须重新单击可编辑的DIV才能开始输入(即使它仍然处于焦点):

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

例如: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.

我不能在处理程序中使用焦点触发器,因为它将创建一个事件循环。所以我需要一种方法来在可编辑的DIV中重新设置插入符号光标,或者以其他方式重新聚焦。

10 个解决方案

#1


23  

You may need to manually update the selection. In IE, the focus event is too late, so I would suggest using the activate event instead. Here's some code that does the job in all major browsers, including IE <= 8 (which a CSS-only alternative will not):

您可能需要手动更新选择。在IE中,焦点事件太晚了,所以我建议使用activate事件。以下是一些在所有主要浏览器中都可以使用的代码,包括IE <= 8(只有css才能使用):

Live demo: http://jsfiddle.net/hHLXr/12/

现场演示:http://jsfiddle.net/hHLXr/12/

Code:

代码:

$('div').on('activate', function() {
    $(this).empty();
    var range, sel;
    if ( (sel = document.selection) && document.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(this);
        range.select();
    }
});

$('div').focus(function() {
    if (this.hasChildNodes() && document.createRange && window.getSelection) {
        $(this).empty();
        var range = document.createRange();
        range.selectNodeContents(this);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
});

#2


149  

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

这里有一个CSS唯一的解决方案,增加了一些其他的答案:-

<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

编辑:这是我在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)

EDIT2:请注意,该方法不能100%用于多行应用程序,因为在所有行上执行select-all-cut或select-all-delete之后,div中仍然存在
元素。学分:- @vsync Backspace似乎运行良好(至少在webkit/blink上)

#3


27  

I've just published a plugin for this.

我刚刚发布了一个插件。

It uses a combination of CSS3 and JavaScript to show the placeholder without adding to the content of the div:

它使用CSS3和JavaScript的组合来显示占位符,而不添加到div的内容:

HTML:

HTML:

<div contenteditable='true' data-placeholder='Enter some text'></div>

CSS:

CSS:

div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
    content: attr(data-placeholder);
    float: left;
    margin-left: 5px;
    color: gray;
}

JS:

JS:

(function ($) {
    $('div[data-placeholder]').on('keydown keypress input', function() {
        if (this.textContent) {
            this.dataset.divPlaceholderContent = 'true';
        }
        else {
            delete(this.dataset.divPlaceholderContent);
        }
    });
})(jQuery);

And that's it.

就是这样。

#4


22  

just use css pseudo-classes.

使用css伪类。

span.spanclass:empty:before {content:"placeholder";}

#5


8  

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

我发现最好的方法是像往常一样使用占位符属性并添加几行CSS。

HTML

HTML

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

CSS

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

Codepen

#6


6  

All you need is this little solution

你所需要的就是这个小小的解决方案

[contenteditable=true]:empty:before{
  content: attr(placeholder);
  display: block; /* For Firefox */
}

Demo: http://codepen.io/flesler/pen/AEIFc

演示:http://codepen.io/flesler/pen/AEIFc

#7


4  

Here's my way:

It uses a combination of jQuery and CSS3. Works exactly like the html5 placeholder attribute!.

我的方法是:它使用jQuery和CSS3的组合。工作方式与html5占位符属性完全相同!

  • Hides itself right away when you input the first letter
  • 当你输入第一个字母时,它会立刻隐藏起来
  • Shows itself again when you delete what you input into it
  • 当您删除输入到其中的内容时,将再次显示自己

HTML:

HTML:

<div class="placeholder" contenteditable="true"></div>

CSS3:

CSS3:

.placeholder:after {
    content: "Your placeholder"; /* this is where you assign the place holder */
    position: absolute;
    top: 10px;
    color: #a9a9a9;
}

jQuery:

jQuery:

$('.placeholder').on('input', function(){
    if ($(this).text().length > 0) {
        $(this).removeClass('placeholder');
    } else {
        $(this).addClass('placeholder');
    }
});

DEMO: http://jsfiddle.net/Tomer123/D78X7/

演示:http://jsfiddle.net/Tomer123/D78X7/

#8


1  

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

为此我开发了一个jQuery插件。看看https://github.com/phitha/editableDiv

#9


0  

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>');
    }
});

#10


0  

This is not exact solution of your problem ..

这不是你问题的正确答案。

in summernote options set

在summernote选项设置

airMode:true

airMode:真

placeholder works in this way.

占位符是这样工作的。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2012/02/01/692ad82180670c19e4fe50feab84762f.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com