可满足的 div 的占位符

我有以下数据: 小提琴

占位符工作得很好,直到您键入某些内容、 ctrl + Adelete。如果这样做,占位符就会消失,再也不会出现。

怎么了? 我怎么能有一个可满足的 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;
}


Thanks.

79357 次浏览

我明白你的意思了。在你的小提琴中,我键入了几个字符,然后用“ ctrl-a”和“ delete”删除了它,占位符又出现了。

然而,似乎当你在 contentedabele div 中点击“ enter”时,它会创建一个子 div,其中包含换行符 <div><br></div>,这会导致: null 伪类的问题,该伪类只针对没有子元素的元素。* *

检查它在铬开发工具或任何你使用。

Developer.mozilla.org

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

Ctrl-a 将删除文本,但保留子 div。也许可以通过添加一些 javascript 来修复这个问题。

正如斯威夫特所说,你可以用一些超级简单的 JS 来解决这个问题。使用 jQuery:

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

在每次按键时,它都会检查是否存在任何输入文本。如果没有,它会删除任何可能由于用户与元素的交互而遗留下来的子元素——例如 <div> swift 描述。

更新 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

我有这个功能,我总是用来防止这种事情。

我是这样使用我的函数的:

var notEmpty = {}


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




neverEmpty(notEmpty)

我只是将 no-void-plz 添加到不希望为空的元素 I 中。

/**
* 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
}

在寻找同样的问题时,我想出了一个简单的 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();
}
});
});

更新小提琴

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

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

一些补救措施:

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

2) data-placeholder attr 代替 placeholder-这是正确的方式

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

4) display: inline-block; - fix for Chrome and 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;
}

可满足焦点事件问题中的占位符

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

我已经创建了一个现场演示: “占位符的内容可编辑 div”,由 HTML 和 CSS。
此外,Codepen: < a href = “ https://Codepen.io/fritx/pen/NZpbqW”rel = “ norefrer”> https://Codepen.io/fritx/pen/nzpbqw
参考文献: < a href = “ https://github.com/fritx/vue-at/questions/39 # issecomment-504412421”rel = “ norefrer”> 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>

我得到了这个解决方案: https://codepen.io/flesler/pen/AEIFc

基本上把这个 css 代码:

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

并在可满足的 div 中包含占位符属性。

这个解决方案对我很有效,我把这个解决方案从有角转换成了纯 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;
}

这对我来说很管用,如果输入太小,它会修剪长的占位符

[contenteditable="true"][placeholder]:empty:before {
content: attr(placeholder);
position: absolute;
left: 5px;
font-size: 13px;
color: #aaa;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
direction: ltr;
}

之所以会发生这种情况,是因为当您 ctrl + A 然后删除时,在 textarea 的 innerHTML 中仍然存在一个 < br > 。一个简单的 jQuery/javascript 解决方案可以清空 textarea:

$(document).on('input','.test',function(){
if(this.innerHTML == '<br>'){
$(this).html('');
}
});

let contenteditableDiv = document.getElementById('contenteditableDiv');


contenteditableDiv.addEventListener('focus', function() {
let phs = this.querySelector('.placeholder-span');
if (phs != null) {
if (!this.hasOwnProperty('placeholderSpan')) {
this.placeholderSpan = phs;
}
phs.remove();
document.getSelection().setPosition(this, 0);
}
});


contenteditableDiv.addEventListener('focusout', function() {
if (this.textContent.trim().length == 0 && this.hasOwnProperty('placeholderSpan')) {
this.replaceChildren(this.placeholderSpan);
}
});
.placeholder-span {
opacity: 0.5;
}
<div id="contenteditableDiv" contenteditable="true"><span class="placeholder-span">Type something...</span></div>

And if You want to avoid contenteditable HTML formatting problems (leading/trailing spaces) and write it like a normal person:

<div id="contenteditableDiv" contenteditable="true">
<span class="placeholder-span">Type something...</span>
</div>

然后加上:

window.addEventListener('load', function() {
let contenteditableDiv = document.getElementById('contenteditableDiv');
contenteditableDiv.innerHtml = contenteditableDiv.innerHtml.trim();
});

如果您希望占位符一直保持到有输入为止,那么您需要在 mousedown、 before input 和 input 事件侦听器中放入适当的逻辑。