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

时间:2012-02-01 09:25:09

标签: javascript jquery focus contenteditable caret

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

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

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

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

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

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

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

11 个答案:

答案 0 :(得分:151)

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

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

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

EDIT2:请注意,由于在执行<br>select-all-cut之后div中存在残余select-all-delete元素,此方法对于多行应用程序无效100%所有线路。致谢: - @vsync
退格似乎工作正常(至少在webkit / blink上)

答案 1 :(得分:28)

我只是published a plugin for this

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

HTML:

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

CSS:

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

JS:

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

就是这样。

答案 2 :(得分:23)

您可能需要手动更新选择。在IE中,焦点事件为时已晚,因此我建议使用activate事件。这里有一些代码可以在所有主流浏览器中完成这项工作,包括IE&lt; = 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);
    }
});

答案 3 :(得分:22)

只需使用css伪类。

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

答案 4 :(得分:8)

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

<强> HTML

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

<强> CSS

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

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

Codepen

答案 5 :(得分:7)

您需要的只是这个小解决方案

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

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

答案 6 :(得分:4)

这是我的方式:

它使用jQuery和CSS3的组合。 与html5占位符属性完全相同!

  • 输入第一个字母时立即隐藏自己
  • 删除您输入的内容时再次显示自己

HTML:

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

CSS3:

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

jQuery的:

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

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

答案 7 :(得分:1)

这是我使用的修复程序。

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

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

答案 8 :(得分: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>');
    }
});

答案 9 :(得分:0)

这不是你问题的确切解决方案..

在summernote选项集中

  

<强> airMode:真

占位符以这种方式工作。

答案 10 :(得分:0)

在.css中

.holder:before {
    content: attr(placeholder);
    color: lightgray;
    display: block;
    position:absolute;    
    font-family: "Campton", sans-serif;
}

在js中。

clickedOnInput:boolean = false;
charactorCount:number = 0;
let charCount = document.getElementsByClassName('edit-box')[0];

if(charCount){
this.charactorCount = charCount.innerText.length;
}

if(charactorCount > 0 && clickedOnInput){
document.getElementById("MyConteditableElement").classList.add('holder');
}

if(charactorCount == 0 && !clickedOnInput){
document.getElementById("MyConteditableElement").classList.remove('holder');
}

getContent(innerText){
  this.clickedOnInput = false;
}

在.html

<div placeholder="Write your message.." id="MyConteditableElement" onclick="clickedOnInput = true;" contenteditable class="form-control edit-box"></div>

此解决方案在我的项目中对我有用