HTML5 占位符在焦点上消失

Posted

技术标签:

【中文标题】HTML5 占位符在焦点上消失【英文标题】:HTML5 placeholder disappears on focus 【发布时间】:2012-01-24 08:27:03 【问题描述】:

是否有免费提供的 jQuery 插件可以更改 placeholder 的行为以匹配 html5 规范?

聚焦前

专注于良好(Safari)

聚焦不良(Chrome、Firefox)

您可以执行浏览器的操作with this simple fiddle。

HTML5 draft spec says:

当元素的值为空字符串和/或控件未聚焦(例如,通过在内部显示一个空白的无焦点控件,否则将其隐藏)。

“/or”在当前草案中是新的,所以我想这就是 Chrome 和 Firefox 还不支持它的原因。见WebKit bug #73629、Chromium bug #103025。

【问题讨论】:

你的小提琴在 Chrome 17.0.963.12 上对我有用(占位符不会在焦点上消失)。 @antisanity 我在开发频道:dev.chromium.org/getting-involved/dev-channel 我最近更新了我的Placeholders.js polyfill 以支持这一点。适用于几乎所有浏览器,包括 IE6,并且不依赖于 jQuery。 当然“例如,通过在空白的未聚焦控件中显示它并在其他情况下隐藏它”意味着规范允许这种行为。我还建议将占位符文本隐藏在焦点上对大多数人来说更有用(我看到有几个人尝试选择占位符文本以在输入前将其删除)。 为什么不相信浏览器正在做正确的工作?浏览器比开发者更清楚什么是最好的方式(每个浏览器都可以根据用户的喜好进行配置)。 【参考方案1】:

Stefano J. Attardi 写了一个很好的 jQuery 插件,它就是这样做的。 它比 Robert 的更稳定,并且在聚焦区域时会逐渐变为浅灰色。

见the demo page 抓住它GitHub 玩the fiddle

我修改了他的插件以读取placeholder 属性,而不是手动创建span。This 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; 

【讨论】:

看起来不错,但是 github repo 两年没更新了……我不愿意使用陈旧的代码。 @ripper:这可能意味着代码可以正常工作吗?我建议你尝试使用它,如果你发现任何问题,请随时 fork 并修复它们。但如果您找到更好的解决方案,请告诉我们。 这可能意味着......这不是很能激发信心......但我想我会试一试。 @ripper:对我来说效果很好,除了一些我记不清的字体大小问题。 你还需要 fields.live('mouseup', toggleLabel);当用户点击 IE 中的重置 ([X]) 图标时显示占位符【参考方案2】:

Robert Nyman 讨论了这个问题并记录了他的方法 in his blog。This fiddle 包含所有必要的 HTML、CSS 和 JS。

不幸的是,他通过更改value解决了这个问题。 如果 placeholder 文本本身是一个有效的输入,则根据定义,这将不起作用。

【讨论】:

【参考方案3】:

我通过谷歌搜索同一问题的解决方案找到了这个问题。似乎现有的插件要么在旧版浏览器中不起作用,要么在焦点上隐藏占位符。

所以我决定推出自己的解决方案,同时尝试结合现有插件的最佳部分。

您可以查看here 并在遇到任何问题时提出问题。

【讨论】:

安德鲁这太棒了!奇迹般有效。感谢您节省了我的时间并且必须自己做:)【参考方案4】:

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

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

【讨论】:

【参考方案5】:

我编写了自己的仅 css3 解决方案。看看这是否满足您的所有需求。

http://codepen.io/f***darga/pen/MayNWm

这是我的解决方案:

    输入元素设置为“必需” 需要为占位符添加一个 span 元素。该元素移动到输入元素的顶部(位置:绝对;) 使用 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;

【讨论】:

【参考方案6】:

也许您可以尝试使用浮动标签模式:)

见Float labels in CSS

【讨论】:

以上是关于HTML5 占位符在焦点上消失的主要内容,如果未能解决你的问题,请参考以下文章

占位符在 Chrome 中聚焦时不会消失

HTML5 输入类型占位符在 IE 中不起作用

JavaScript 使HTML5占位符在非支持性浏览器中工作

占位符怎么设置

在 Chrome 中清除焦点上的 HTML5 占位符属性文本

占位符在 IE 中无法正常工作,但适用于 Chrome