在本机不支持它的浏览器中模拟“占位符”属性的最准确方法是什么?

时间:2011-04-07 03:30:17

标签: jquery forms html5 user-experience placeholder

最近我一直在研究jquery / javascript解决方案来模拟placeholder属性,但它们似乎都没有。常见问题是:

  • 首先不使用本机浏览器支持
  • 表单实际上可以发布占位符文本的值
  • 如果值相同,则无法识别占位符文本和用户输入(嘿,我的电子邮件是IS user@example.com !!为什么不提交?嘿我想搜索字符串“搜索“但它不会让我!”
  • 难以设计或区分常规文本和占位符文本
  • 突兀的实施(几乎总是。我不想为每个输入添加2个div,并使用样式表来执行此操作)
  • 只是不行。 jQuery网站上至少有2个。

我已经玩了一些试图让它正常工作(从我已经看到的一些代码中获得一些提示),但它仍然需要工作。特别是,表单可以发布占位符的值。 Comments and mods to the jsfiddle are welcome(注意:必须在没有占位符支持的情况下在浏览器中查看演示)我见过的大多数代码都会使用placeholder的值并将其填充到输入本身,从而导致此问题,我觉得必须有更好的方法。

是否有一个很好的清洁解决方案 实际上

编辑:我想强调一下:它应该像你在尽可能原生支持它的浏览器中看到的那样,并且尽可能 un 突出,如我目前所示代码,除了包含脚本和使用placeholder之外的其他任何代码都不需要像通常那样支持它的浏览器。

更新:@DA目前的解决方案是完美的一些错误修复(见评论),很想看到这个100%汇集在一起​​,并把所有的错误和放在一起网上的错误代码令人羞愧。

更新:使用DA代码的几个mod工作,但它仍然不完美,主要是关于动态添加的输入字段和现有的submit()绑定。感谢所有的帮助,我现在已经决定它不值得。我知道有些人肯定会使用这个。这是一个很好的技巧,但对我来说,即使是1%的可能性,表单提交做不想做的事情,或者错误地阅读用户输入,也不值得。这个小功能不值得头疼,IE和好友只能处理它,或者如果真的需要它可以根据具体情况实现,就像客户要求它一样。 @DA再次感谢,这是我见过的最佳实现。

结论:我认为解决所有这些问题的唯一方法是:

  • 将占位符值复制到新的块级元素
  • 将新元素添加到输入
  • 计算输入的高度边框和填充,并将新元素移动到尽可能接近文本位置的位置
  • 使用标准模糊/更改/焦点事件在输入具有值或焦点时隐藏元素

通过这种方式,您无需在提交或处理可能发生的任何其他问题时执行任何操作。抱歉,还没有演示,我必须重新开始工作 - 但是我会保存一个最终的编辑,以便它们结合在一起。

4 个答案:

答案 0 :(得分:4)

“我见过的大多数代码都占用了占位符的值,并将其填充到输入本身,导致了这个问题”

嗯,这几乎就是占位符文本在幕后所做的事情(虽然它并没有真正更新输入的值)。

一种选择是类似于此:

http://fuelyourcoding.com/scripts/infield/

这个概念是你用CSS移动LABEL,使其位于字段之上,看起来像占位符文本。请注意,LABEL不一定与占位符文本相同。 LABEL非常重要,特别是对于可访问性而言,除了标签之外,占位符文本可以更多地被视为“帮助文本”。

另一个选项是你一直在做的事情,获取占位符属性的内容,并通过JS将其移动到输入本身的值。

如果你被挂断了,你是在提交表格之前检查假的占位符文本是否仍在那里。

要解决这个问题,您需要在提交表单时附加一个事件,在提交表单之前,首先查看所有输入字段,获取其值,将其与占位符属性进行比较,如果是匹配,将值设置为空白。

更新:

要解决您在与占位符文本匹配的用户输入值的注释中提出的问题,您可以执行以下操作:

$('input[placeholder]').each(function(){

 if($(this).val() === $(this).attr('placeholder')){
      // in the odd situation where the field is prepopulated with
      // a value and the value just happens to match the placeholder,
      // then we need to flag it
      $(this).data('skipCompare','true');
  }    

// move the placeholder text into the field for the rest of the blank inputs
   if($(this).val().length===0){
       $(this).val($(this).attr('placeholder'))
   }

// move the placeholder text into the field for the rest of the blank inputs
  if($(this).val().length===0){
      $(this).val() = $(this).attr('placeholder');
  }


  $(this)
     .focus(function(){
           // remove placeholder text on focus
           if($(this).val()==$(this).attr('placeholder')){
               $(this).val('')
           }
     })
     .blur(function(){
         // flag fields that the user edits
         if( $(this).val().length>0 && $(this).val()==$(this).attr('placeholder')){
             $(this).data('skipCompare','true');
         }
         if ( $(this).val().length==0){
             // put the placeholder text back
             $(this).val($(this).attr('placeholder'));
         }
     })


 })

 $('#submitButton').click(function(){
   $('input[placeholder]').each(function(){
     if( !($(this).data('skipCompare')) && $(this).val() == $(this).attr('placeholder')     ){
         $(this).val('');
     };
     alert($(this).val());
   })
})

已经很晚了,我累了所以这可能是完全错误的。没有保证。 ;)

答案 1 :(得分:2)

我刚才写的

jquery插件:

(function(){
    $.fn.inactiveText = function(inactiveClass, defaultValue){
        var a, b;
        this
            .data    ('defaultValue', defaultValue)
            .addClass('inactive')
            .focus(a=function(){
                var $this = $(this);
                if($this.hasClass(inactiveClass)){
                    (valFn.apply($this) == defaultValue) && $this.val('');
                    (valFn.apply($this) != defaultValue) && $this.removeClass(inactiveClass);
                }
    //            $this.hasClass(inactiveClass) && $this.valueIs(defaultValue).val('').end().valueIsNot(defaultValue).removeClass(inactiveClass);
            })
            .blur(b=function(){
                var $this = $(this);
                this.value || $this.addClass(inactiveClass).val(defaultValue);
            });
        this.each(a);
        this.each(b);

        this.setDefaultValue = function(d){
            this.each(a);
            defaultValue = d;
            this.each(b);
        };

        return this;
    };

    var valFn = $.fn.val;

    $.fn.val = function(v){
        if(typeof(v) == 'undefined'){
            var val = valFn.apply(this, arguments);
            return val == this.data('defaultValue') ? '' : val;
        }

        return valFn.apply(this, arguments);
    };
})();

为非活动样式定义一个css类(例如灰色文本),你就可以了。

更新小提琴:http://jsfiddle.net/cwolves/At8cu/1/

答案 2 :(得分:1)

假设定义了jQuery。

$(document).ready(function() {
    // Use native functionality if possible
    if (document.createElement('input').placeholder !== undefined) return;
    // Fallback code
    $('form').each(function(i, form) {
        var submitted = false;
        $(form).find('input[placeholder]').each(function(j, input) {
            addPlaceholder.call(input);
            $(input)
                .focus(removePlaceholder)
                .blur(addPlaceholder)
                ;
        });
        $(form).submit(function() {
            submitted = true;
            $(this).find('input[placeholder]').each(function(j, input) {
                removePlaceholder.call(input);
            });
        });
        function addPlaceholder() {
            if (!submitted && '' === $(this).val()) {
                $(this).val($(this).attr('placeholder')).addClass('placeholder');
            }
        }
        function removePlaceholder() {
            if ( $(this).hasClass('placeholder') &&
                 $(this).attr('placeholder') === $(this).val()
                 ) {
                $(this).val('').removeClass('placeholder');
            }
        }
    });
});

使用CSS设置占位符的样式,使其在所有浏览器中看起来都一样:

            :-moz-placeholder { color: #bbb; opacity: 1; }
           ::-moz-placeholder { color: #bbb; opacity: 1; }
       :-ms-input-placeholder { color: #bbb; }
  ::-webkit-input-placeholder { color: #bbb; }
                 .placeholder { color: #bbb; }

答案 3 :(得分:0)