contenteditable div 的占位符
Posted
技术标签:
【中文标题】contenteditable div 的占位符【英文标题】:Placeholder for contenteditable div 【发布时间】:2014-01-10 15:31:35 【问题描述】:我有以下内容: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 .. 也不能删除占位符文本。 它在 Chrome 上运行良好,您使用的是哪个浏览器? 在 FF 上也能正常工作 我正在使用 Firefox,但它无法正常工作(是的,我有最新的更新)。 :// 不知道 CSSattr()
- 谢谢!
【参考方案1】:
我明白你的意思。在你的小提琴中,我输入了几个字符并使用'ctrl-a'和'delete'将其删除,占位符重新出现。
但是,似乎当您在 contenteditabele div 中点击“输入”时,它会创建一个包含换行符 <div><br></div>
的子 div,这会导致 :empty 伪类出现问题,该伪类仅针对没有子元素。**
在 chrome 开发人员工具或您使用的任何工具中查看。
来自 developer.mozilla.org
:empty 伪类表示任何没有子元素的元素。仅考虑元素节点和文本(包括空格)。注释或处理指令不会影响元素是否被视为空。
Ctrl-a 将删除文本,但保留子 div。或许可以通过添加一些 javascript 来解决这个问题。
【讨论】:
好地方 -<div><br></div>
:)【参考方案2】:
正如斯威夫特所说,你可以用一些超级简单的 JS 来解决这个问题。使用 jQuery:
var $input = $(".test");
$input.keyup(function ()
if ($input.text().length == 0)
$input.empty();
);
在每次击键时,它都会检查是否存在任何输入文本。如果不是,它会破坏用户与元素交互可能留下的任何子元素——例如<div>
斯威夫特描述。
【讨论】:
+1 不错,但在更多情况下可能会发生这种情况(右键单击 + 剪切)。【参考方案3】:更新 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://***.com/q/17796731
$input.bind('input', (clearPlaceHolder));
// Other strange events (javascript modification of value?)
$input.change(clearPlaceHolder);
最后,updated JSFiddle
【讨论】:
谢谢弗朗西斯科,比我的更全面,也很清晰。【参考方案4】:我有这个功能,而且我总是用来防止这种事情发生。
我是这样使用我的函数的:
var notEmpty =
notEmpty.selector = ".no-empty-plz"
notEmpty.event = "focusout"
notEmpty.nonEmpty = "---"
neverEmpty(notEmpty)
我只是将 no-empty-plz 添加到我不想为空的元素中。
/**
* 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 也是我创建的另一个 fucntion,类似于修剪,但包括   和 <br/>,
等
function hardTrim(text)
if (!exists(text))
return ""
text = text.replace(/^\ \;|<br?\>*/gi, "").replace(/\ \;|<br?\>$/gi, "").trim();
return text
【讨论】:
【参考方案5】:在寻找同样的问题时,我想出了一个简单的混合 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();
);
);
Updated fiddle
【讨论】:
我的页面加载时如何获取占位符?它工作得很好,但是在我输入了一些内容并删除了输入字段中的所有内容之后它就开始了。 也许你的元素不是空的?上面的代码只过滤空格,而不是换行符。 占位符应该保留,除非您输入内容。这消失了。 对于您的假设行为,只需从 css 中删除[placeholder]:empty:focus:before
元素。
请加cursor: text;
,否则显示占位符时光标会变成箭头【参考方案6】:
感觉就像我在重复自己,但为什么不检查contenteditable
元素突变呢?试图将所有内容绑定到正在更改内容的事件是一件很痛苦的事情。如果您需要添加按钮(例如粘贴)或动态更改内容(javascript)怎么办。我的方法是使用MutationObservers。演示fiddle
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);
【讨论】:
【参考方案7】:一些修复:
1) $element.text().trim().length
- 它解决了 <div><br/></div>
和 &nbsp;
的问题
2) data-placeholder
attr 而不是 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;
【讨论】:
这个解决方案删除了 在 div 中如果你需要 在里面【参考方案8】:来自Placeholder in contenteditable - focus event issue
[contenteditable=true]:empty:not(:focus):before
content:attr(data-ph);
color:grey;
font-style:italic;
【讨论】:
当 div contenteditable 为空并且我加载页面时,它不会显示任何内容。占位符在我输入后才起作用,然后我用退格键清除 div contenteditable。如果一开始就想要怎么办 基于 CSS 的最佳解决方案。【参考方案9】:我创建了一个现场演示:“内容可编辑 div 的占位符”,由 HTML 和 CSS 编写。 另外,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>
【讨论】:
【参考方案10】:我的解决方案来自:https://codepen.io/flesler/pen/AEIFc
基本上放这个css代码:
[contenteditable=true]:empty:before
content: attr(placeholder);
pointer-events: none;
display: block; /* For Firefox */
并且在你的 contenteditable div 中有 placeholder 属性。
【讨论】:
这很漂亮 这非常酷,适合许多用例,谢谢! 这是完美的,为什么这不是更高的! 答案不错,但并不完美。必须有 javascript 来清除为 contenteditable div 中的新行创建的 break 标记和 div 标记。为了证明这一点,请在可编辑的 div 中输入一些内容,然后单击 enter 以创建新行。然后按 control+A 选择所有文本并用退格键删除。结果??没有占位符了【参考方案11】:这个解决方案对我有用。我已将此解决方案从 angular 转换为纯 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 div 的占位符的主要内容,如果未能解决你的问题,请参考以下文章
css CSS - 对contentEditable元素的占位符支持
如何将光标位置放在 contenteditable 元素的居中对齐占位符的开头?
如果已经在 contenteditable 上打字,则禁用打字机功能