可信赖的div的占位符

时间:2013-12-22 04:07:51

标签: javascript jquery html css

我有以下内容: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; 
}

<小时/> 感谢。

12 个答案:

答案 0 :(得分:54)

在搜索同样的问题时,我想出了一个简单的混合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

答案 1 :(得分:11)

来自Placeholder in contenteditable - focus event issue

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

答案 2 :(得分:4)

一些修正:

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

答案 3 :(得分:4)

我从https://codepen.io/flesler/pen/AEIFc

获得了此解决方案

基本上放置以下CSS代码:

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

在内容可编辑的div中具有占位符属性。

答案 4 :(得分:3)

我明白你的意思了。在你的小提琴中,我输入了几个字符并使用'ctrl-a'和'delete'删除它,并且占位符重新出现。

然而,似乎当你在contenteditabele div中点击'enter'时,它创建了一个包含换行符<div><br></div>的子div,它创建了一个问题:empty伪类只针对元素没有子元素。**

在Chrome开发人员工具或您使用的任何工具中查看它。

来自developer.mozilla.org

  

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

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

答案 5 :(得分:3)

感觉就像我在重复自己,但为什么不检查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);

答案 6 :(得分:2)

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

最后,updated JSFiddle

答案 7 :(得分:1)

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

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

在每次击键时,它会检查是否存在任何输入文本。如果没有,它会破坏用户与元素交互可能留下的任何子元素 - 例如<div> swifft描述。

答案 8 :(得分:1)

此解决方案对我有用。我已经将此解决方案从有角度的转换为纯javaScript

在.html

import React, { useEffect, useState } from 'react';
import { Redirect, Route } from 'react-router-dom';

export default function ProtectedRoute({ component: Component, ...rest }) {
     // add fetchingUser state with defaut is true
     const [ fetchingUser, setFetchingUser ] = useState(true);
    const [ user, setUser ] = useState('');

    useEffect(() => {
        const fetchUser = async () => {
            try {
                const response = await fetch('http://localhost:5000/user', {
                    credentials: 'include'
                });

                const data = await response.json();
                setUser(data.session.passport.user);
                // setFetching is false here
                setFetchingUser(false)

            } catch (error) {
                // You can create an error state and set error here
                console.log(error);
            }
        }

        fetchUser();

        return () => {
         // Do some cleanup   
        }
    }, [])
  
  
  // add fetchingUser into conditions
  // You can do better job that is if fetching show Loading component
  // If error show error component
  // if not fetching not error and have user show user component
  // if not fetching not error and not user redirect to login
    return (
         <Route { ...rest } render={ () => user && !fetchingUser ? <Component /> : <Redirect to="/login" /> }/>
    )
}

在.css中

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

在js中。

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

答案 9 :(得分:0)

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

我以这种方式使用我的功能:

var notEmpty = {}

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


    neverEmpty(notEmpty)

我只是将无空的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也是我创建的另一个功能就像修剪但包括&amp; nbsp和<br/>,

function hardTrim(text) {

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

    return text
}

答案 10 :(得分:0)

我已经通过HTML和CSS创建了一个实时演示:“内容可编辑div的占位符”。
另外,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>

答案 11 :(得分:-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'));
        }
    }
});