Platzhalter für contenteditable div

78

Ich habe folgendes: FIDDLE

Der Platzhalter funktioniert einwandfrei, bis Sie etwas eingeben, ctrl+ Aunddelete . Wenn Sie dies tun, verschwindet der Platzhalter und wird nie wieder angezeigt.

Was ist los? Wie kann ich einen Platzhalter für ein inhaltsbearbeitbares Div haben?

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


Vielen Dank.

Bagwell
quelle
Welchen Browser verwenden Sie? Ich kann weder Strg + a drücken noch den Platzhaltertext löschen.
Milche Patern
10
es funktioniert gut mit mir auf Chrome welchen Browser benutzt du?
Yehia Awad
Funktioniert auch gut mit FF
Roko C. Buljan
Ich benutze Firefox und es funktioniert nicht (und ja, ich habe das neueste Update). : /
Bagwell
2
Wusste nichts über CSS attr()- danke!
Candu

Antworten:

72

Bei der Suche nach demselben Problem habe ich eine einfache gemischte CSS-JavaScript-Lösung ausgearbeitet, die ich gerne teilen möchte:

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

Geige aktualisiert

Eternal1
quelle
Wie erhalte ich den Platzhalter, wenn meine Seite geladen wird? Es funktioniert perfekt, aber es kommt, nachdem ich etwas eingegeben und alles im Eingabefeld gelöscht habe.
Nishan Weerasinghe
Vielleicht ist dein Element nicht leer? Der obige Code filtert nur Leerzeichen, nicht beispielsweise Zeilenumbrüche.
Ewige1
Platzhalter soll bleiben, es sei denn, Sie geben etwas ein. das verblasst.
Mayankcpdixit
3
Für Ihr vermeintliches Verhalten entfernen Sie einfach das [placeholder]:empty:focus:beforeElement aus CSS.
Eternal1
1
Bitte fügen Sie hinzu, cursor: text;sonst ist der Cursor der Pfeil, wenn der Platzhalter
angezeigt wird
22

von Platzhalter in contenteditable - Fokus Ereignisproblem

[contentEditable=true]:empty:not(:focus):before{
  content:attr(data-ph);
  color:grey;
  font-style:italic;
}
nicolas
quelle
1
Wenn div contenteditable leer ist und ich eine Seite lade, wird mir nichts angezeigt. Platzhalter funktioniert nur, nachdem ich ihn eingegeben habe, und dann lösche ich div contenteditable mit Rücktaste. Was kann ich tun, wenn ich es am Anfang will
Mohammed Jawad Barati
16

Ich habe eine Live-Demo von HTML & CSS erstellt: "Platzhalter für inhaltsbearbeitbare Divs".
Codepen: https://codepen.io/fritx/pen/NZpbqW
Ref: 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>

Fritz Lin
quelle
5

Einige Korrekturen:

1) $element.text().trim().length- es löste Probleme mit <div><br/></div>und&nbsp;

2) data-placeholderattr statt placeholder- es ist wahr

3) gemeinsamer Selektor $("[contenteditable]")- es ist wahr

4) display: inline-block;- Fix für Chrome und 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;
}
comerc
quelle
4

Ich verstehe was du meinst. In Ihrer Geige habe ich einige Zeichen eingegeben und sie mit 'Strg-A' und 'Löschen' gelöscht, und der Platzhalter ist wieder aufgetaucht.

Es scheint jedoch, als würde beim Drücken der Eingabetaste in der Datei contenteditabele div ein untergeordnetes div erstellt, das den Zeilenumbruch enthält, <div><br></div>wodurch ein Problem mit der leeren Pseudoklasse entsteht, das nur auf Elemente ohne untergeordnete Elemente abzielt. **

Probieren Sie es in den Chrome-Entwicklertools oder was auch immer Sie verwenden aus.

Von developer.mozilla.org

Die: leere Pseudoklasse repräsentiert jedes Element, das überhaupt keine Kinder hat. Es werden nur Elementknoten und Text (einschließlich Leerzeichen) berücksichtigt. Kommentare oder Verarbeitungsanweisungen haben keinen Einfluss darauf, ob ein Element als leer betrachtet wird oder nicht.

Strg-a löscht den Text, lässt aber das untergeordnete div. Könnte in der Lage sein, dies durch Hinzufügen von Javascript zu beheben.

swifft
quelle
schöner Ort - <div><br></div>:)
David
3

Es fühlt sich an, als würde ich mich wiederholen, aber warum nicht contenteditableElementmutationen überprüfen ? Der Versuch, alles an Ereignisse zu binden, die den Inhalt ändern, ist ein Schmerz im Hintern. Was ist, wenn Sie eine Schaltfläche hinzufügen (z. B. Einfügen) oder den Inhalt dynamisch ändern müssen (Javascript)? Mein Ansatz wäre die Verwendung von MutationObservers . Demo Geige

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);
Bogdan Kuštan
quelle
3

Ich habe diese Lösung erhalten von: https://codepen.io/flesler/pen/AEIFc

Grundsätzlich setzen Sie diesen CSS-Code:

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

Und haben Sie das Platzhalterattribut in Ihrem inhaltsbearbeitbaren div.

Ege Hurturk
quelle
2

Wenn Sie die Antwort von Christian Brink aktualisieren, können / sollten Sie nach weiteren Ereignissen suchen. Sie können dies tun, indem Sie einfach Folgendes tun:

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

Endlich die aktualisierte JSFiddle

Francisco Presencia
quelle
1
Danke Francisco, umfassender als meiner und sehr klar.
Christian Brink
1

Wie gesagt, Sie können dies mit einem supereinfachen JS beheben. Verwenden von jQuery:

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

Bei jedem Tastendruck wird geprüft, ob Eingabetext vorhanden ist. Wenn nicht, werden alle untergeordneten Elemente geschlagen, die möglicherweise durch die Benutzerinteraktion mit dem Element zurückgelassen wurden - z <div>. B. die Beschreibung, die der Swifft beschreibt.

Christian Brink
quelle
1
+1 Schön, aber es gibt noch weitere Situationen, in denen dies passieren könnte (Rechtsklick + Ausschneiden).
Francisco Presencia
1

Diese Lösung hat bei mir funktioniert. Ich hatte diese Lösung von eckigem zu reinem JavaScript konvertiert

In .html

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

In .css

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

in 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;
}
Sahil Ralkar
quelle
0

Ich habe diese Funktion und benutze sie immer, um solche Dinge zu verhindern.

Ich benutze meine Funktion folgendermaßen:

var notEmpty = {}

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


    neverEmpty(notEmpty)

Und ich füge einfach das no-empty-plz zu den Elementen hinzu, die ich nicht leer sein möchte.

/**
     * 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 ist eigentlich ein json, also selector = params.selector, wie Sie sehen können

Und hardTrim ist auch eine andere Funktion, die ich erstellt habe. Sie ist wie eine Trimmung, enthält jedoch & nbsp und <br/>,etc.

function hardTrim(text) {

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

    return text
}
luisZavaleta
quelle
-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'));
        }
    }
});
Иван Гончаренко
quelle