占位符在满足 - 焦点事件问题

Dav*_*ing 61 javascript jquery focus caret contenteditable

我以前一直试图问这个,没有任何运气解释/证明一个错误发生的工作示例.所以这是另一个尝试:

我试图在一个可信的DIV上复制一个占位符效应.核心概念很简单:

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

<script>
$('div').focus(function() {
    $(this).empty();
});
</script>
Run Code Online (Sandbox Code Playgroud)

这可能有些工作,但如果占位符包含HTML,或者正在进行其他处理,则可删除可编辑DIV的文本插入符,并且用户必须重新单击可编辑的DIV才能开始键入(即使它是仍然是焦点):

示例:http://jsfiddle.net/hHLXr/6/

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

mrm*_*oje 154

这是一个仅限CSS的解决方案,增加了一些其他答案: -

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

编辑:这是我在codepen上的代码片段 - > http://codepen.io/mrmoje/pen/lkLez

EDIT2:请注意,这种方法对于多行应用程序不起作用100%,因为<br>在执行a select-all-cutselect-all-delete所有行之后div中存在残余元素.致谢: - @vsync
Backspace似乎工作正常(至少在webkit/blink上)

  • 这应该是公认的答案.它比@amwinter的更复杂,但它将占位符保留在html而不是css中. (7认同)

Cra*_*ntz 29

我刚刚为此发布了一个插件.

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

HTML:

<div contenteditable='true' data-placeholder='Enter some text'></div>
Run Code Online (Sandbox Code Playgroud)

CSS:

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

JS:

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

就是这样.


Tim*_*own 25

您可能需要手动更新选择.在IE中,焦点事件为时已晚,因此我建议使用该activate事件.这里有一些代码可以在所有主流浏览器中完成,包括IE <= 8(仅限CSS的替代方案):

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

码:

$('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);
    }
});
Run Code Online (Sandbox Code Playgroud)


amw*_*ter 22

只需使用css伪类.

span.spanclass:empty:before {content:"placeholder";}
Run Code Online (Sandbox Code Playgroud)


ram*_*amo 8

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

HTML

<div contenteditable placeholder="I am a placeholder"></div>
Run Code Online (Sandbox Code Playgroud)

CSS

[contenteditable][placeholder]:empty:before {
    content: attr(placeholder);
    color: #bababa;
}
Run Code Online (Sandbox Code Playgroud)

注意::empty只有在开始和结束标记之间没有任何内容时,CSS 选择器才有效.这包括新行,标签,空白等.

Codepen


wp *_*ent 7

你只需要这个小解决方案

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

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

  • 在 Chrome 中遇到此方法的问题,您必须单击两次才能放置插入符号,**如果您右键单击占位符**。通过添加“pointer-events: none;”(在您的 codepen css 中找到)解决了这个问题。在此提及那些正在寻找特定 Chrome 问题解决方案的人。 (2认同)