Заповнювач для задоволеного div


81

У мене є таке: 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 .. ні видалити текст заповнювача.
Milche Patern

10
він добре працює зі мною на chrome, який браузер ви використовуєте?
Yehia Awad

Також чудово працює на FF
Роко С. Бульян

Я використовую Firefox, і він не працює (і так, у мене останнє оновлення). : /
Bagwell

2
Не знав про CSS attr()- дякую!
candu

Відповіді:


76

Під час пошуку тієї самої проблеми я розробив просте змішане рішення 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

Можливо, ваш елемент не порожній? Наведений вище код фільтрує лише пробіли, а не, скажімо, розриви рядків.
Вічний1

власник місця повинен залишитися, якщо ви щось не введете. це зникає.
mayankcpdixit

3
Для вашої передбачуваної поведінки просто видаліть [placeholder]:empty:focus:beforeелемент з css.
Вічний1

1
Будь ласка, додайте, cursor: text;інакше курсором буде стрілка, коли відображатиметься заповнювач
gztomas

23

від заповнювача в задоволеному - фокус питання події

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

1
коли div contenteditable порожній, і я завантажую сторінку, це нічого не показує. заповнювач просто працює після того, як я в нього вводжу, а потім я очищаю div contenteditable з backspace. що я можу зробити, якщо хочу цього на початку
Мохаммад Джавад Бараті

17

Я створив демонстрацію в реальному часі: "Заповнювач для редагованих вмістом divs", 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>


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', і заповнювач знову з'явився.

Однак, здається, ніби коли ви натискаєте клавішу «enter» у межах contenteditabele div, це створює дочірній div, що містить розрив рядка, <div><br></div>створюючи проблему з псевдокласом: empty, який націлений лише на елементи без дочірніх елементів. **

Перевірте це в інструментах розробника chrome або будь-якому іншому, що ви використовуєте.

Від developer.mozilla.org

Псевдо-клас: empty представляє будь-який елемент, який взагалі не має дочірніх елементів. Враховуються лише вузли елементів та текст (включаючи пробіли). Коментарі чи інструкції з обробки не впливають на те, чи вважається елемент порожнім чи ні.

Ctrl-a видалить текст, але залишить дочірній div. Можливо, це вдасться виправити, додавши трохи JavaScript.


приємне місце - <div><br></div>:)
Девід

4

Я отримав це рішення з: https://codepen.io/flesler/pen/AEIFc

В основному покладіть цей css-код:

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

І вкажіть атрибут placeholder у своєму задоволеному div.


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

Оновляючи відповідь Крістіана Брінка, ви могли / повинні перевірити наявність інших подій. Ви можете зробити це, просто виконавши:

// 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
Дякую Франциско, більш вичерпний, ніж мій, і дуже чіткий.
Крістіан Брінк

1

Як сказав Swifft, ви можете виправити це за допомогою надзвичайно простих JS. Використання jQuery:

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

При кожному натисканні клавіші він перевіряє, чи присутній вхідний текст. Якщо ні, він ударить будь-які дочірні елементи, які могли бути залишені через взаємодію користувача з елементом - наприклад, <div>описується swifft.


1
+1 Приємно, але є й інші ситуації, коли це може статися (клацніть правою кнопкою миші + виріжте).
Francisco Presencia,

1

Це рішення спрацювало для мене. Я перетворив це рішення з 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;
}

0

У мене є ця функція, і я завжди використовую, щоб запобігти подібним речам.

Я використовую свою функцію таким чином:

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 - це ще одна функція, яку я створив, схожа на обробку, але включає & 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'));
        }
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.