可编辑div的占位符


78

我有以下内容:FIDDLE

占位符可以很好地工作,直到您输入ctrl+A和为止delete。如果这样做,则占位符将消失并且不再显示。

怎么了?如何为内容可编辑的div使用占位符?

HTML:

<div class="test" placeholder="Type something..." contenteditable="true"></div>


CSS:

.test {
    width: 500px;
    height: 70px;
    background: #f5f5f5;
    border: 1px solid #ddd;
    padding: 5px;
}

.test[placeholder]:empty:before {
    content: attr(placeholder);
    color: #555; 
}


谢谢。


你使用的是什么浏览器?我无法ctrl + a ..也无法删除占位符文本。
米歇尔·帕特恩

10
在chrome上与我合作正常,您使用的是哪种浏览器?
Yehia Awad 2013年

在FF上也能正常工作
Roko C. Buljan 2013年

我正在使用Firefox,但无法正常工作(是的,我有最新更新)。:/
Bagwell 2013年

2
不了解CSS-attr()谢谢!
candu 2014年

Answers:


72

在搜索相同问题时,我想出一个简单的css-JavaScript混合解决方案,我想分享一下:

CSS:

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

[placeholder]:empty:focus::before {
    content: "";
}

JavaScript:

jQuery(function($){
    $("[contenteditable]").focusout(function(){
        var element = $(this);        
        if (!element.text().trim().length) {
            element.empty();
        }
    });
});

更新的小提琴


页面加载时如何获取占位符?它运行正常,但是在我键入一些内容并清除了输入字段中的所有内容后才开始运行。
Nishan Weerasinghe 2015年

也许您的元素不为空?上面的代码仅过滤空格,而不是换行符。
Eternal1 2015年

除非您输入内容,否则占位符应该保留。这消失了。
mayankcpdixit 2015年

3
对于您应有的行为,只需[placeholder]:empty:focus:before从CSS中删除元素。
永恒2015年

1
请添加,cursor: text;否则显示占位符时,光标将为箭头
gztomas

22

来自内容可编辑的占位符-焦点事件问题

[contentEditable=true]:empty:not(:focus):before{
  content:attr(data-ph);
  color:grey;
  font-style:italic;
}

1
当div contenteditable为空并且我加载页面时,它什么都没有显示。占位符仅在我键入它后起作用,然后我清除可通过Backspace编辑的div content。如果我一开始想要它该怎么办
Mohammad limbad Barati

16

我已经创建了一个实时演示:HTML和CSS的“内容可编辑div的占位符”。
另外,Codepen:https
: //codepen.io/fritx/pen/NZpbqW参考:https : //github.com/fritx/vue-at/issues/39#issuecomment-504412421

.editor {
  border: solid 1px gray;
  width: 300px;
  height: 100px;
  padding: 6px;
  overflow: scroll;
}
[contenteditable][placeholder]:empty:before {
  content: attr(placeholder);
  position: absolute;
  color: gray;
  background-color: transparent;
}
<textarea class="editor"
  placeholder="Textarea placeholder..."
></textarea>
<br/>
<br/>
<div class="editor"
  contenteditable
  placeholder="Div placeholder..."
  oninput="if(this.innerHTML.trim()==='<br>')this.innerHTML=''"
></div>


5

一些修复:

1)$element.text().trim().length-解决了<div><br/></div>和的问题&nbsp;

2)data-placeholderattr代替placeholder-这是正确的方法

3)通用选择器$("[contenteditable]")-这是正确的方法

4)display: inline-block;-修复了Chrome和Firefox

JavaScript:

jQuery(function($){
    $("[contenteditable]").blur(function(){
        var $element = $(this);
        if ($element.html().length && !$element.text().trim().length) {
            $element.empty();
        }
    });
});

HTML:

<div data-placeholder="Type something..." contenteditable="true"></div>

CSS:

[contenteditable]:empty:before {
    content: attr(data-placeholder);
    color: grey;
    display: inline-block;
}

4

我明白你的意思了。在您的提琴中,我输入了几个字符,然后使用“ ctrl-a”和“ delete”将其删除,然后重新出现了占位符。

但是,似乎当您在contenteditabele div中单击“ enter”时,它会创建一个包含换行符的子div,<div><br></div>从而产生:empty伪类的问题,该伪类仅针对没有子元素的元素。**

在chrome开发人员工具或您使用的任何工具中进行检查。

来自developer.mozilla.org

:empty伪类表示任何根本没有子元素的元素。仅考虑元素节点和文本(包括空格)。注释或处理指令不会影响元素是否为空。

Ctrl-a将删除文本,但保留子div。可能可以通过添加一些JavaScript来解决此问题。


好地方- <div><br></div>:)
David

3

感觉就像我在重复自己,但是为什么不检查contenteditable元素突变呢?试图将所有内容绑定到内容不断变化的事件上,这无疑是痛苦的。如果您需要添加按钮(例如粘贴)或动态更改内容(javascript)该怎么办。我的方法是使用MutationObservers。演示小提琴

HTML:

<div class="test" id="test" placeholder="Type something..." contenteditable="true"></div>

CSS:

.test {
    width: 500px;
    height: 70px;
    background: #f5f5f5;
    border: 1px solid #ddd;
    padding: 5px;
}

.test[placeholder]:empty:before {
    content: attr(placeholder);
    color: #555; 
}

JavaScript:

var target = document.querySelector('#test');
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
      if (target.textContent == '') {
          target.innerHTML = '';
      }
  });    
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);


2

更新Christian Brink的答案,您可以/应该检查更多事件。您只需执行以下操作即可:

// More descriptive name
var $input = $(".placeholder");
function clearPlaceHolder() {
  if ($input.text().length == 0) {
    $input.empty();
    }
  }

// On each click
$input.keyup(clearPlaceHolder);

// Probably not needed, but just in case
$input.click(clearPlaceHolder);

// Copy/paste/cut events http://stackoverflow.com/q/17796731
$input.bind('input', (clearPlaceHolder));

// Other strange events (javascript modification of value?)
$input.change(clearPlaceHolder);

最后,更新的JSFiddle


1
谢谢弗朗西斯科,比我的要全面得多,也很清楚。
Christian Brink 2014年

1

正如swifft所说,您可以使用一些超级简单的JS来解决此问题。使用jQuery:

var $input = $(".test");
$input.keyup(function () {
    if ($input.text().length == 0) {
        $input.empty();
    }
});

在每次击键时,它都会检查是否存在任何输入文本。如果没有,它将对用户与该元素的交互可能遗留下来的<div>任何子元素进行重击,例如swifft描述。


1
+1不错,但是在更多情况下可能会发生这种情况(右键单击+剪切)。
弗朗西斯科·普雷森西亚

1

这个解决方案对我有用。我已经将此解决方案从角度转换为纯javaScript

在.html中

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

在.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;
}

0

我具有此功能,并且我总是使用它来防止此类情况。

我以这种方式使用我的功能:

var notEmpty = {}

    notEmpty.selector = ".no-empty-plz"
    notEmpty.event = "focusout"
    notEmpty.nonEmpty = "---"


    neverEmpty(notEmpty)

我只是将no-empty-plz添加到不想为空的Elements中。

/**
     * Used to prevent a element have a empty content, made to be used 
when we want to edit the content directly with the contenteditable=true 
because when a element is completely empty, it disappears U_U
     * 
     * @param selector
     * @param event
     * @param nonEmpty:
     *        String to be put instead empty
     */
function neverEmpty(params) {

    var element = $(params.selector)



    $(document).on(params.event, params.selector, function() {

        var text = $(this).html()
        text = hardTrim(text)

        if ($.trim(text)  == "") {
            $(this).html(params.nonEmpty)
        }
    });
}

params实际上是一个json,因此如您所见,selector = params.selector

而且hardTrim也是我创建的另一个功能,例如修剪,但包含&nbsp<br/>,

function hardTrim(text) {

    if (!exists(text)) {
        return ""
    }
    text = text.replace(/^\&nbsp\;|<br?\>*/gi, "").replace(/\&nbsp\;|<br?\>$/gi, "").trim();

    return text
}

-1
<div id="write_comment" contenteditable="true"></div>

var placeholderCommentText = 'Comment...',
    placeholderComment = $('#write_comment').attr('placeholder', placeholderCommentText);

$('#write_comment').text(placeholderCommentText);

$('[contenteditable]').bind({
    focus: function(){
        if ($('#write_comment').text().length == 0 || $('#write_comment').text() == $('#write_comment').attr('placeholder')) {
            $(this).empty();
        }
        $(this).keyup(function(){
            if ($('#write_comment').text() == $('#write_comment').attr('placeholder')){
                $('#write_comment').attr('placeholder','');
            } else if ($('#write_comment').text().length == 0 ) {
                $('#write_comment').attr('placeholder', placeholderCommentText);
            }
        });
    },
    focusout: function(){
        if ($('#write_comment').text().length == 0) { 
            $(this).text($(this).attr('placeholder'));
        }
    }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.