IE9中的占位符

141

这似乎是一个非常常见的问题,但我在谷歌上找到的所有解决方法都无法在我新下载的IE9上起作用。

您最喜欢的启用inputtextarea标记上的Placeholder属性的方法是什么?

可选:我在这方面浪费了很多时间,还没有寻找required属性。您对此有什么建议吗?显然,我可以在PHP中检查该值,但为了帮助用户,此属性非常方便。


我在停留了4年后回到HTML领域。这意味着我乐于接受任何建议来替换我的过时工具。我几乎从零开始重新开始。我一直在尝试使用jQuery,并从谷歌搜索结果中复制/粘贴很多内容,这是我的最新尝试 - chriscatfr
11个回答

186

1
我将 GitHub 的 JS 文件复制到我的 SRC 代码中,但占位符仍然无法正常工作。 - Philo
2
这确实非常好用,不过在单页应用程序上使用起来很麻烦。你需要手动触发它以使用动态添加的字段。除此之外,一切都运作良好! - smets.kevin
@smets.kevin 你说需要手动触发,是什么意思?我遇到了一个问题,即使使用插件,我的占位符仍然会加载为“null”,直到我删除null,然后正确的占位符在输入失去焦点时才出现。我尝试使用jQuery ID调用placeholder()函数,但仍无法使其正常工作... - tjfo
1
谢谢,插件很不错,但我遇到一个问题,就是在ie9中,当文本输入框获得焦点时,占位符会消失。这与HTML5的行为不同。 - gerrytan
1
它的表现很好,但有一个大问题,当输入为空时,$('input').val()返回占位符的值。因为我正在使用AJAX框架,这些占位符会被发送到服务器... - Danubian Sailor
显示剩余5条评论

21

我认为这就是你要找的内容:jquery-html5-placeholder-fix

这个解决方案使用特性检测(通过modernizr)来确定是否支持placeholder。如果不支持,则通过jQuery添加支持。


2
它能运行,但不是最好的代码。在顶部,应该将 $(this) 分配给一个变量,以便在整个代码中使用。每次使用 $(this) 的表达式都调用 $ 是一个大忌,直接违反了“不要像这样编写 jQuery 101”的规则。 - Sami Samhuri
20
在提交表单时,要小心此代码,因为占位符的值将作为表单值进行提交。在提交之前应该清除它。 - ericbae
由于我对HTML5功能的竞争还很陌生,因此很好奇:是Modernizer导致这成为一个不好的解决方案,还是jquery-html5-placeholder-fix本身(或两者都有)? - Snekse
更新的链接修复了上面评论中提到的问题:http://kamikazemusic.com/web-development/revisiting-html5-placeholder-fixes/ - Brent
请注意,需要使用Modernizer脚本和HTML输入功能。 - Brent

17
如果您不想使用jQuery或Modernizer,可以使用以下代码:
(function(){

     "use strict";

     //shim for String's trim function..
     function trim(string){
         return string.trim ? string.trim() : string.replace(/^\s+|\s+$/g, "");
     }

     //returns whether the given element has the given class name..
     function hasClassName(element, className){ 
         //refactoring of Prototype's function..
         var elClassName = element.className;
         if(!elClassName)
             return false;
         var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
         return regex.test(element.className);
     }

     function removeClassName(element, className){
         //refactoring of Prototype's function..
         var elClassName = element.className;
         if(!elClassName)
             return;
         element.className = elClassName.replace(
             new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ');
     }

     function addClassName(element, className){
         var elClassName = element.className;
         if(elClassName)
             element.className += " " + className;
         else
             element.className = className;
     }

     //strings to make event attachment x-browser.. 
     var addEvent = document.addEventListener ?
            'addEventListener' : 'attachEvent';
     var eventPrefix = document.addEventListener ? '' : 'on';

     //the class which is added when the placeholder is being used..
     var placeHolderClassName = 'usingPlaceHolder';

     //allows the given textField to use it's placeholder attribute
     //as if it's functionality is supported natively..
     window.placeHolder = function(textField){

         //don't do anything if you get it for free..
         if('placeholder' in document.createElement('input'))
             return;

         //don't do anything if the place holder attribute is not
         //defined or is blank..
         var placeHolder = textField.getAttribute('placeholder');        
         if(!placeHolder)
             return;

         //if it's just the empty string do nothing..
         placeHolder = trim(placeHolder);
         if(placeHolder === '')
             return;

         //called on blur - sets the value to the place holder if it's empty..
         var onBlur = function(){
             if(textField.value !== '') //a space is a valid input..
                 return;
             textField.value = placeHolder;
             addClassName(textField, placeHolderClassName);
         };

         //the blur event..
         textField[addEvent](eventPrefix + 'blur', onBlur, false);

         //the focus event - removes the place holder if required..
         textField[addEvent](eventPrefix + 'focus', function(){
             if(hasClassName(textField, placeHolderClassName)){
                removeClassName(textField, placeHolderClassName);
                textField.value = "";
             }
         }, false);

         //the submit event on the form to which it's associated - if the
         //placeholder is attached set the value to be empty..
         var form = textField.form;
         if(form){
             form[addEvent](eventPrefix + 'submit', function(){
                 if(hasClassName(textField, placeHolderClassName))
                     textField.value = '';
            }, false);
         }

         onBlur(); //call the onBlur to set it initially..
    };

}());

对于你想使用的每个文本字段,您需要运行placeHolder(HTMLInputElement),但我猜您可以根据情况进行更改!另外,这样做,而不仅仅是在加载时进行,意味着您可以使其适用于在页面加载时不在DOM中的输入。
请注意,这是通过将类usingPlaceHolder应用于输入元素来工作的,因此您可以使用它来进行样式设置(例如,添加规则.usingPlaceHolder { color: #999; font-style: italic; }使其看起来更好)。

1
抱歉 - 我真的不知道这是否容易实现 - 我猜你想要显示实际文本值,而不是“符号”。我能想到的唯一hack方法是,除非它有焦点或值,否则将其替换为文本输入,否则将其显示为密码字段。 - Mark Rhodes
@StephenPatten 请看一下我为密码字段占位符所做的修复。我正是按照Mark建议的方式进行的 :) - Chev

8
这里有一个更好的解决方案。 http://bavotasan.com/2011/html5-placeholder-jquery-fix/ 我稍微修改了它,使其仅适用于IE10以下的浏览器。
<!DOCTYPE html>
<!--[if lt IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
<!--[if IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8" lang="en"> <![endif]-->
<!--[if IE 8]><html class="no-js lt-ie10 lt-ie9" lang="en"> <![endif]-->
<!--[if IE 9]><html class="no-js lt-ie10" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--><html class="no-js" lang="en"><!--<![endif]-->

    <script>
    // Placeholder fix for IE
      $('.lt-ie10 [placeholder]').focus(function() {
        var i = $(this);
        if(i.val() == i.attr('placeholder')) {
          i.val('').removeClass('placeholder');
          if(i.hasClass('password')) {
            i.removeClass('password');
            this.type='password';
          }     
        }
      }).blur(function() {
        var i = $(this);  
        if(i.val() == '' || i.val() == i.attr('placeholder')) {
          if(this.type=='password') {
            i.addClass('password');
            this.type='text';
          }
          i.addClass('placeholder').val(i.attr('placeholder'));
        }
      }).blur().parents('form').submit(function() {
        //if($(this).validationEngine('validate')) { // If using validationEngine
          $(this).find('[placeholder]').each(function() {
            var i = $(this);
            if(i.val() == i.attr('placeholder'))
              i.val('');
              i.removeClass('placeholder');

          })
        //}
      });
    </script>
    ...
    </html>

无法在IE8上工作,因为IE不允许jQuery操作输入类型(请查看2011年12月20日下午1:48在http://bavotasan.com/2011/html5-placeholder-jquery-fix/上的Bill评论)。 - forste
也假设您正在提交表单。我见过的大多数单页面应用程序都不使用表单,而是使用点击处理程序。 - chovy

5
如果您想输入描述,可以使用此功能。该功能在IE 9和所有其他浏览器上均可使用。
<input type="text" onclick="if(this.value=='CVC2: '){this.value='';}" onblur="if(this.value==''){this.value='CVC2: ';}" value="CVC2: "/>

1
我自己没有测试过,但是猜测如果你通过制表符切换到该字段而不是单击它,则无法正常工作。我在许多网站上看到了这个错误,或者类似的错误。 - eselk
使用这个解决方案,您还需要在提交表单时检查此值。 - Igor Jerosimić
我很惊讶这个得到了任何票数,即使在2012/2013年发布时也不应该使用。 - LocalPCGuy
如果您在输入时写入应该是占位符(“CV2:”)的内容,那么您输入的内容将被删除。 - Daniel

2
使用 mordernizr 来检测不支持 Placeholder 的浏览器,我编写了以下代码来修复它们。
//If placeholder is not supported
if (!Modernizr.input.placeholder){ 

    //Loops on inputs and place the placeholder attribute
    //in the textbox.
    $("input[type=text]").each( function() { 
       $(this).val($(this).attr('placeholder')); 
    })
}

2
你必须小心处理这段代码,因为如果你提交表单,占位符的值将会被一并提交。在它被提交之前,你应该清除它。 - chriscatfr
3
在这个例子中,如果我的占位符是“密码”,而我的真实密码确实是“密码”,那么应该如何正确地操作? - Lain
你可以使用 "dirty" 的概念来处理这样的字段。在输入时将该字段标记为 clean (可能使用 data-dirty="false")。如果他们提交表单而没有更改占位符文本,则会发现该字段是 clean 的,因此请清除它。如果他们确实更改了它甚至改成了与占位符相同的值,则它就是 dirty 的,您需要提交那个值。 - oooyaya
有关密码和其他解决方案,请查看https://jsfiddle.net/AlexanderPatel/1pv2174c/3/。 - Shirish Patel
最后,如果一个元素没有任何占位符怎么办? 最终集合应该被过滤为 .filter('[placeholder]') - jave.web
显示剩余2条评论

2
我知道我来晚了,但我发现在头部插入以下标签可以解决问题:

<meta http-equiv="X-UA-Compatible" content="IE=edge"/> <!--FIX jQuery INTERNET EXPLORER-->


你在IE9中测试过吗?否则,IE10+支持占位符... - jave.web
当然,这很奇怪,IE9本身不支持标签打开它 - 那时它是一个实验性的功能吗?这在哪里有参考资料? :) - jave.web

1

有点晚了,但我使用我的经过验证的JS,利用Modernizr。可以复制/粘贴并应用于任何项目。每次都有效:

// Placeholder fallback
if(!Modernizr.input.placeholder){

    $('[placeholder]').focus(function() {
      var input = $(this);
      if (input.val() == input.attr('placeholder')) {
        input.val('');
        input.removeClass('placeholder');
      }
    }).blur(function() {
      var input = $(this);
      if (input.val() == '' || input.val() == input.attr('placeholder')) {
        input.addClass('placeholder');
        input.val(input.attr('placeholder'));
      }
    }).blur();
    $('[placeholder]').parents('form').submit(function() {
      $(this).find('[placeholder]').each(function() {
        var input = $(this);
        if (input.val() == input.attr('placeholder')) {
          input.val('');
        }
      })
    });

}

所有这些解决方案都使用jQuery..难道没有不需要臃肿的jQuery的解决方案吗? - Spock

1

要在IE-9中使其工作,请使用以下内容。这对我有效。

需要包括JQuery:

jQuery(function() {
   jQuery.support.placeholder = false;
   webkit_type = document.createElement('input');
   if('placeholder' in webkit_type) jQuery.support.placeholder = true;});
   $(function() {

     if(!$.support.placeholder) {

       var active = document.activeElement;

       $(':text, textarea, :password').focus(function () {

       if (($(this).attr('placeholder')) && ($(this).attr('placeholder').length > 0) &&         ($(this).attr('placeholder') != '') && $(this).val() == $(this).attr('placeholder')) {
          $(this).val('').removeClass('hasPlaceholder');
        }
      }).blur(function () {
if (($(this).attr('placeholder')) && ($(this).attr('placeholder').length > 0) &&  ($(this).attr('placeholder') != '') && ($(this).val() == '' || $(this).val() ==   $(this).attr('placeholder'))) {
     $(this).val($(this).attr('placeholder')).addClass('hasPlaceholder');
}
});

$(':text, textarea, :password').blur();
$(active).focus();
$('form').submit(function () {
     $(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
});
}
});

CSS样式需要包括:
.hasPlaceholder {color: #aaa;}

1
你应该修复你的格式,比如添加缩进并将你的答案与代码分开。 - Darren Shewry

0

我通常对http://cdnjs.com/评价很高,他们正在列出:

//cdnjs.cloudflare.com/ajax/libs/placeholder-shiv/0.2/placeholder-shiv.js

不确定这是谁的代码,但它看起来很简单:

document.observe('dom:loaded', function(){
  var _test = document.createElement('input');
  if( ! ('placeholder' in _test) ){
    //we are in the presence of a less-capable browser
    $$('*[placeholder]').each(function(elm){
      if($F(elm) == ''){
        var originalColor = elm.getStyle('color');
        var hint = elm.readAttribute('placeholder');
        elm.setStyle('color:gray').setValue(hint);
        elm.observe('focus',function(evt){
          if($F(this) == hint){
            this.clear().setStyle({color: originalColor});
          }
        });
        elm.observe('blur', function(evt){
          if($F(this) == ''){
            this.setValue(hint).setStyle('color:gray');
          }
        });
      }
    }).first().up('form').observe('submit', function(evt){
      evt.stop();
      this.select('*[placeholder]').each(function(elm){
        if($F(elm) == elm.readAttribute('placeholder')) elm.clear();
      });
      this.submit();
    });
  }
});

1
此插件需要原型库。 - rosswil

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