在contenteditable中的占位符—焦點事件問題

[英]Placeholder in contenteditable - focus event issue


I have been trying to ask this before, without any luck of explaining/proving a working example where the bug happens. So here is another try:

我之前一直在試着問這個問題,沒有任何解釋/證明bug發生的例子。這是另一個嘗試:

I’m trying to replicate a placeholder effect on a contenteditable DIV. The core concept is simple:

我試圖在contenteditable DIV上復制占位符效應。

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

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

This can sometomes work, but if the placeholder contains HTML, or if there some other processing being made, the editable DIV’s text caret is being removed, and the user must re-click the editable DIV to be able to start typing (even if it’s still in focus):

這可以起到一些作用,但是如果占位符包含HTML,或者正在進行其他處理,那么可編輯的DIV的文本插入符號將被刪除,並且用戶必須重新單擊可編輯的DIV才能開始輸入(即使它仍然處於焦點):

Example: http://jsfiddle.net/hHLXr/6/

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

I can’t use a focus trigger in the handler, since it will create an event loop. So I need a way to re-set the caret cursor in the editable DIV, or in some other way re-focus.

我不能在處理程序中使用焦點觸發器,因為它將創建一個事件循環。所以我需要一種方法來在可編輯的DIV中重新設置插入符號光標,或者以其他方式重新聚焦。

10 个解决方案

#1


23  

You may need to manually update the selection. In IE, the focus event is too late, so I would suggest using the activate event instead. Here's some code that does the job in all major browsers, including IE <= 8 (which a CSS-only alternative will not):

您可能需要手動更新選擇。在IE中,焦點事件太晚了,所以我建議使用activate事件。以下是一些在所有主要瀏覽器中都可以使用的代碼,包括IE <= 8(只有css才能使用):

Live demo: http://jsfiddle.net/hHLXr/12/

現場演示:http://jsfiddle.net/hHLXr/12/

Code:

代碼:

$('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);
    }
});

#2


149  

Here is a CSS only solution augmenting some of the other answers:-

這里有一個CSS唯一的解決方案,增加了一些其他的答案:-

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

EDIT: Here is my snippet on codepen -> http://codepen.io/mrmoje/pen/lkLez

編輯:這是我在codepen ->上的代碼片段http://codepen.io/mrmoje/pen/lkLez

EDIT2: Be advised, this method doesn't work 100% for multi-line applications due to residual <br> elements being present in the div after performing a select-all-cut or select-all-delete on all lines. Credits:- @vsync
Backspace seems to work fine (at least on webkit/blink)

EDIT2:請注意,該方法不能100%用於多行應用程序,因為在所有行上執行select-all-cut或select-all-delete之后,div中仍然存在
元素。學分:- @vsync Backspace似乎運行良好(至少在webkit/blink上)

#3


27  

I've just published a plugin for this.

我剛剛發布了一個插件。

It uses a combination of CSS3 and JavaScript to show the placeholder without adding to the content of the div:

它使用CSS3和JavaScript的組合來顯示占位符,而不添加到div的內容:

HTML:

HTML:

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

CSS:

CSS:

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

JS:

JS:

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

And that's it.

就是這樣。

#4


22  

just use css pseudo-classes.

使用css偽類。

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

#5


8  

I found that the best way to do this is to use the placeholder attribute like usual and add a few lines of CSS.

我發現最好的方法是像往常一樣使用占位符屬性並添加幾行CSS。

HTML

HTML

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

CSS

CSS

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

Note: the CSS :empty selector only works if there is literally nothing in-between the opening and closing tag. This includes new lines, tabs, empty space, etc.

注意:空選擇器只在打開和關閉標簽之間沒有任何內容時才工作。這包括新的行、制表符、空空間等。

Codepen

Codepen

#6


6  

All you need is this little solution

你所需要的就是這個小小的解決方案

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

Demo: http://codepen.io/flesler/pen/AEIFc

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

#7


4  

Here's my way:

It uses a combination of jQuery and CSS3. Works exactly like the html5 placeholder attribute!.

我的方法是:它使用jQuery和CSS3的組合。工作方式與html5占位符屬性完全相同!

  • Hides itself right away when you input the first letter
  • 當你輸入第一個字母時,它會立刻隱藏起來
  • Shows itself again when you delete what you input into it
  • 當您刪除輸入到其中的內容時,將再次顯示自己

HTML:

HTML:

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

CSS3:

CSS3:

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

jQuery:

jQuery:

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

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

演示:http://jsfiddle.net/Tomer123/D78X7/

#8


1  

Here's the fix that I used.

這是我使用的修復方法。

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

I developed a jQuery plug-in for this. Take a look https://github.com/phitha/editableDiv

為此我開發了一個jQuery插件。看看https://github.com/phitha/editableDiv

#9


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

#10


0  

This is not exact solution of your problem ..

這不是你問題的正確答案。

in summernote options set

在summernote選項設置

airMode:true

airMode:真

placeholder works in this way.

占位符是這樣工作的。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2012/02/01/692ad82180670c19e4fe50feab84762f.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com