HTML5占位符在焦点时消失

27

是否有一个免费的jQuery插件可以改变placeholder的行为以符合HTML5规范?

未聚焦时
chrome unfocused placeholder

焦点聚集时良好(Safari)
safari focused placeholder

焦点聚集时不佳(Chrome,Firefox)
chrome focused placeholder

您可以使用此简单的fiddle来测试浏览器的行为。

HTML5草案规范说

用户代理应该在从其中删除换行符后,将这个提示呈现给用户,当元素的值是空字符串和/或控件没有聚焦(例如通过在空白未聚焦控件内显示它并在其他情况下隐藏它)时。

“/或”在当前草案中是新的,所以我想这就是Chrome和Firefox尚未支持它的原因。请参阅WebKit bug #73629Chromium bug #103025


1
你的小提琴在Chrome 17.0.963.12上对我有效(占位符在焦点上不会消失)。 - ThinkingStiff
1
@antisanity 我在开发频道上:http://dev.chromium.org/getting-involved/dev-channel - ThinkingStiff
1
我最近更新了我的Placeholders.js polyfill以支持此功能。它可以在几乎所有浏览器中运行,包括IE6,并且不依赖于jQuery。 - James Allardice
2
当然,“例如通过在空白未聚焦的控件内显示它并在其他情况下隐藏它”意味着该行为是规范允许的。我还建议,在焦点上隐藏占位符文本对于大多数人来说更加可用(我看过几个人尝试选择占位符文本以删除它,然后再输入)。 - pelms
1
为什么不相信浏览器正在做正确的工作呢?浏览器比开发者更清楚最佳方式(每个浏览器都可以根据用户的喜好进行配置)。 - brunoais
显示剩余3条评论
6个回答

15

Stefano标签

Stefano J. Attardi编写了一个不错的jQuery插件,可以实现文本框标签效果。
它比Robert的插件更稳定,并且在字段获得焦点时会淡化为浅灰色。


我修改了他的插件,使其可以读取placeholder属性,而不是手动创建span
这个fiddle包含完整的代码:

HTML

<input type="text" placeholder="Hello, world!">

JS

// Original code by Stefano J. Attardi, MIT license

(function($) {
    function toggleLabel() {
        var input = $(this);

        if (!input.parent().hasClass('placeholder')) {
            var label = $('<label>').addClass('placeholder');
            input.wrap(label);

            var span = $('<span>');
            span.text(input.attr('placeholder'))
            input.removeAttr('placeholder');
            span.insertBefore(input);
        }

        setTimeout(function() {
            var def = input.attr('title');
            if (!input.val() || (input.val() == def)) {
                input.prev('span').css('visibility', '');
                if (def) {
                    var dummy = $('<label></label>').text(def).css('visibility','hidden').appendTo('body');
                    input.prev('span').css('margin-left', dummy.width() + 3 + 'px');
                    dummy.remove();
                }
            } else {
                input.prev('span').css('visibility', 'hidden');
            }
        }, 0);
    };

    function resetField() {
        var def = $(this).attr('title');
        if (!$(this).val() || ($(this).val() == def)) {
            $(this).val(def);
            $(this).prev('span').css('visibility', '');
        }
    };

    var fields = $('input, textarea');

    fields.live('mouseup', toggleLabel); // needed for IE reset icon [X]
    fields.live('keydown', toggleLabel);
    fields.live('paste', toggleLabel);
    fields.live('focusin', function() {
        $(this).prev('span').css('color', '#ccc');
    });
    fields.live('focusout', function() {
        $(this).prev('span').css('color', '#999');
    });

    $(function() {
       $('input[placeholder], textarea[placeholder]').each(
           function() { toggleLabel.call(this); }
       );
    });

})(jQuery);

CSS

.placeholder {
  background: white;
  float: left;
  clear: both;
}
.placeholder span {
  position: absolute;
  padding: 5px;
  margin-left: 3px;
  color: #999;
}
.placeholder input, .placeholder textarea {
  position: relative;
  margin: 0;
  border-width: 1px;
  padding: 6px;
  background: transparent;
  font: inherit;
}

/* Hack to remove Safari's extra padding. Remove if you don't care about pixel-perfection. */
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .placeholder input, .placeholder textarea { padding: 4px; }
}

4
@ripper:这可能意味着代码可以直接使用。我建议你尝试使用它,如果发现任何问题,请随意派生它并修复。但如果你找到了更好的解决方案,请让我们知道。 - Dan Abramov
这可能意味着......它并不是非常令人信服......但我想我会试一试。 - ripper234
@ripper:对我来说,它运行得相当不错,除了一些字体大小问题,我无法确切地回忆起来。 - Dan Abramov
1
你还需要添加 fields.live('mouseup', toggleLabel); 代码,以便在用户单击 IE 浏览器中的重置 ([X]) 图标时显示占位符。 - xorcus
"live"已被弃用。对于当前版本的JQuery,请将所有实例中的"live"替换为"on"。 - Whatever Man
显示剩余2条评论

4

Robert Nyman在他的博客中讨论了这个问题并记录了他的解决方法
这个fiddle包含了所有必要的HTML、CSS和JS代码。

enter image description here

不幸的是,他通过改变value来解决这个问题。
根据定义,如果placeholder文本本身就是有效输入,则这种方法将无效。


3
我是通过谷歌搜索解决同样问题的答案而找到了这个问题。似乎现有的插件要么不能在旧浏览器中运行,要么会在焦点上隐藏占位符。
因此,我决定自己解决问题,同时尝试结合现有插件的优点。
您可以在这里查看,并在面临任何问题时打开一个问题。

Andrew, 这太棒了!运行得很顺畅。感谢你为我节省时间,免去了我自己动手的麻烦 :) - RamRovi

2

像这样的简单方式怎么样?在焦点上保存占位符属性值并完全删除该属性;失去焦点时,将属性放回:

$('input[type="text"]').focus( function(){
  $(this).attr("data-placeholder",$(this).attr('placeholder')).removeAttr("placeholder");
});
$('input[type="text"]').blur( function(){
  $(this).attr("placeholder",$(this).attr('data-placeholder'));
});   

1
我写了自己的仅基于CSS3的解决方案。看看它是否满足您的所有需求。

http://codepen.io/fabiandarga/pen/MayNWm

这是我的解决方案:
  1. 将输入元素设置为“required”
  2. 需要额外的span元素作为占位符。该元素被移动到输入元素的顶部(position:absolute;)
  3. 使用CSS选择器测试输入元素的有效性(如果没有输入,则必填字段无效),然后隐藏占位符

陷阱: 占位符会阻挡鼠标事件到输入框!解决该问题的方法是,在鼠标在父容器内时隐藏占位符元素。

<div class="wrapper">
  <input txpe="text" autofocus="autofocus" required/>
  <span class="placeholder">Hier text</span>
</div>

.placeholder {
  display: none;
  position: absolute;
  left: 0px;
  right: 0;
  top: 0px;
  color: #A1A1A1;
}
input:invalid + .placeholder {
  display: block;  /* show the placeholder as long as the "required" field is empty */
}
.wrapper:hover .placeholder {
  display: none; /* required to guarantee the input is clickable */
}

.wrapper{
  position: relative;
  display: inline-block;
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接