占位符在Internet Explorer中无法正常工作

23

下面是我的文本框的占位符在Internet Explorer中无法工作。有没有办法在Internet Explorer中显示文本框的占位符?

<asp:TextBox id="email" runat="server" width="300" placeholder="您的电子邮件" />

是否可以通过使用JavaScript来简单地解决?我不想使用jQuery使它变得复杂。


将第11行改为:if (!curInput.type || curInput.type == "" || curInput.type == "text" || curInput.type == "password") ...这样它也适用于密码字段! - Christian Lundahl
1
占位符属性不应作为标签的替代品使用。 - Quentin
1
“我不想使用jQuery使它变得复杂。” - 我认为被接受的解决方案比等效的jQuery要复杂得多。 - TygerKrash
只有在您已经包含jQuery的情况下才能执行此操作。 - Tom
对于现在来到这个问题的任何人,无论是在几年后,请注意:(a)IE10及以上版本已经完全支持“placeholder”属性,(b)许多polyfills脚本可以从此处获取 - Spudley
显示剩余2条评论
7个回答

50

您可以使用纯JavaScript来模仿此操作:

var _debug = false;
var _placeholderSupport = function() {
    var t = document.createElement("input");
    t.type = "text";
    return (typeof t.placeholder !== "undefined");
}();

window.onload = function() {
    var arrInputs = document.getElementsByTagName("input");
    var arrTextareas = document.getElementsByTagName("textarea");
    var combinedArray = [];
    for (var i = 0; i < arrInputs.length; i++)
        combinedArray.push(arrInputs[i]);
    for (var i = 0; i < arrTextareas.length; i++)
        combinedArray.push(arrTextareas[i]);
    for (var i = 0; i < combinedArray.length; i++) {
        var curInput = combinedArray[i];
        if (!curInput.type || curInput.type == "" || curInput.type == "text" || curInput.type == "textarea")
            HandlePlaceholder(curInput);
        else if (curInput.type == "password")
            ReplaceWithText(curInput);
    }

    if (!_placeholderSupport) {
        for (var i = 0; i < document.forms.length; i++) {
            var oForm = document.forms[i];
            if (oForm.attachEvent) {
                oForm.attachEvent("onsubmit", function() {
                    PlaceholderFormSubmit(oForm);
                });
            }
            else if (oForm.addEventListener)
                oForm.addEventListener("submit", function() {
                    PlaceholderFormSubmit(oForm);
                }, false);
        }
    }
};

function PlaceholderFormSubmit(oForm) {    
    for (var i = 0; i < oForm.elements.length; i++) {
        var curElement = oForm.elements[i];
        HandlePlaceholderItemSubmit(curElement);
    }
}

function HandlePlaceholderItemSubmit(element) {
    if (element.name) {
        var curPlaceholder = element.getAttribute("placeholder");
        if (curPlaceholder && curPlaceholder.length > 0 && element.value === curPlaceholder) {
            element.value = "";
            window.setTimeout(function() {
                element.value = curPlaceholder;
            }, 100);
        }
    }
}

function ReplaceWithText(oPasswordTextbox) {
    if (_placeholderSupport)
        return;
    var oTextbox = document.createElement("input");
    oTextbox.type = "text";
    oTextbox.id = oPasswordTextbox.id;
    oTextbox.name = oPasswordTextbox.name;
    //oTextbox.style = oPasswordTextbox.style;
    oTextbox.className = oPasswordTextbox.className;
    for (var i = 0; i < oPasswordTextbox.attributes.length; i++) {
        var curName = oPasswordTextbox.attributes.item(i).nodeName;
        var curValue = oPasswordTextbox.attributes.item(i).nodeValue;
        if (curName !== "type" && curName !== "name") {
            oTextbox.setAttribute(curName, curValue);
        }
    }
    oTextbox.originalTextbox = oPasswordTextbox;
    oPasswordTextbox.parentNode.replaceChild(oTextbox, oPasswordTextbox);
    HandlePlaceholder(oTextbox);
    if (!_placeholderSupport) {
        oPasswordTextbox.onblur = function() {
            if (this.dummyTextbox && this.value.length === 0) {
                this.parentNode.replaceChild(this.dummyTextbox, this);
            }
        };
    }
}

function HandlePlaceholder(oTextbox) {
    if (!_placeholderSupport) {
        var curPlaceholder = oTextbox.getAttribute("placeholder");
        if (curPlaceholder && curPlaceholder.length > 0) {
            Debug("Placeholder found for input box '" + oTextbox.name + "': " + curPlaceholder);
            oTextbox.value = curPlaceholder;
            oTextbox.setAttribute("old_color", oTextbox.style.color);
            oTextbox.style.color = "#c0c0c0";
            oTextbox.onfocus = function() {
                var _this = this;
                if (this.originalTextbox) {
                    _this = this.originalTextbox;
                    _this.dummyTextbox = this;
                    this.parentNode.replaceChild(this.originalTextbox, this);
                    _this.focus();
                }
                Debug("input box '" + _this.name + "' focus");
                _this.style.color = _this.getAttribute("old_color");
                if (_this.value === curPlaceholder)
                    _this.value = "";
            };
            oTextbox.onblur = function() {
                var _this = this;
                Debug("input box '" + _this.name + "' blur");
                if (_this.value === "") {
                    _this.style.color = "#c0c0c0";
                    _this.value = curPlaceholder;
                }
            };
        }
        else {
            Debug("input box '" + oTextbox.name + "' does not have placeholder attribute");
        }
    }
    else {
        Debug("browser has native support for placeholder");
    }
}

function Debug(msg) {
    if (typeof _debug !== "undefined" && _debug) {
        var oConsole = document.getElementById("Console");
        if (!oConsole) {
            oConsole = document.createElement("div");
            oConsole.id = "Console";
            document.body.appendChild(oConsole);
        }
        oConsole.innerHTML += msg + "<br />";
    }
}

如果浏览器已经支持placeholder属性,则此操作不会产生任何效果;如果不支持(例如浏览器为IE),则将添加非常相似的功能 - 默认显示的文本在焦点消失并且用户未输入任何内容时重新出现。

实时测试案例

错误修复

2012年11月6日:之前的代码无法检测到浏览器没有对占位符提供原生支持。使用在此其他帖子中找到的代码进行了修复。受影响的浏览器:IE7和IE8,可能还有其他浏览器。还添加了调试支持以帮助调试未来的问题。

2013年1月30日

  1. 同时添加了对密码输入的支持。由于IE8及以下版本不允许动态更改输入类型,因此只要没有输入密码,该代码就会将密码输入替换为文本输入,从而可以看到占位符文本。

  2. 修正了提交与输入相关联的表单时导致发送占位符值的错误。为此,将代码附加到表单提交事件上,并在需要时清除该值。

2014年1月24日:添加对<textarea>元素的支持。


2
哇,谢谢!我在整个互联网上搜索了一个IE兼容的占位符备用方案。终于找到了这一个。 - Baseer
@Mark 抱歉让你久等了,我没有收到你评论的通知。已找到并修复了这个 bug,现在它也能在那些浏览器上正常工作了。感谢你提供的信息! - Shadow The Spring Wizard
1
先生,您用这个脚本为我提供了巨大的帮助。我已经苦苦挣扎了好几天来解决这个问题,但是有了这个漂亮的脚本,我所需要做的就是复制粘贴,然后一切都能正常工作。我无法感谢您的足够!! - Trevor Dupp
我想为文本区域显示一个占位符。我复制粘贴了上面的代码。尽管该控件有占位符属性,但它并没有显示出来,我是否漏掉了什么? - user1447718
@user1447718 谢谢,这是我疏忽了,现在已经添加了对文本区域的支持。如果您还有任何问题,请告诉我。 :) - Shadow The Spring Wizard
显示剩余4条评论

3
有一些填充脚本可供使用,可以为不支持该技术的浏览器添加占位符支持。
建议您访问这里:https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills,并向下滚动约三分之一到名为“Web Forms:input placeholder”的部分,以获取几个不同的选项(包括原生JS和jQuery)。由于整个页面由HTML5 Boilerplate团队策划,因此您可以相当确定所提供的脚本质量较高。
编辑:刚看到您的评论,不要使用HTML5。我提供的链接上的脚本即使在不使用HTML5 doctype的情况下仍应起作用(不做任何明示或暗示的保证)。

3

我写了这段简单的代码,在测试时它运行得很好:

placeholder=function(){
    $('input, textarea').each(function(){
        var holder=$(this).attr('placeholder');
        if(typeof(holder) !=='undefined'){
            $(this).val(holder);
            $(this).bind('click',function(){
                $(this).val('');
            }).blur(function(){
                $(this).val(holder);
            });
        }
    });
};
$(document).ready(placeholder);

你的代码在IE中可以正常运行,但在Firefox和Google Chrome浏览器中出现问题,即占位符文本变粗,如果我点击它,则输入框中会出现普通字体,我无法看到输入的数据。为了调试,我将DOM准备从底部移除并添加到顶部,在FF和GC中的问题似乎已经解决,但在IE中占位符仍然存在问题。 - user2086641
很棒的东西!但是我把函数初始化放进了一个条件里,像这样 if( $.browser.msie && $.browser.version <= '9.0' )。非常感谢! - user621639

0
你可以使用JavaScript Polyfill使占位符在旧浏览器上工作。有许多Polyfills可用。这里是一个关于如何使IE中的占位符工作的例子。基本上,所有这些脚本所做的就是使用JavaScript模拟浏览器本地占位符支持的行为。

0
我最近遇到了这个问题 - 我使用modernizr来检测HTML5功能,然后为无法处理的浏览器运行一些js代码:
    function addPlaceHolder(input) {//using modernizr add placeholder text for non html5 users
    if (!Modernizr.input.placeholder) { 
        input.focus(function () {
            if (input.val() == input.attr('placeholder')) {
                input.val('');
                input.removeClass('placeholder');
            }
        }).blur(function () {
            if (input.val() == '' || input.val() == input.attr('placeholder')) {
                input.addClass('placeholder');
                input.val(input.attr('placeholder'));
            }
        }).blur();
        $(input).parents('form').submit(function () {
            $(this).find(input).each(function () {
                if (input.val() == input.attr('placeholder')) {
                    input.val('');
                }
            })
        });
    }
}

addPlaceHolder($('#Myinput'));

对我来说似乎很好用!


0

占位符是HTML5的一个特性。为了解决这个问题,我检测MSIE并执行以下操作:

if ( $.browser.msie ) {
    $("#textarea-id").val('placeholder');
    $("#textarea-id").focus(function(){
        this.select();
    });
}

这是jQuery,但不是那么复杂...


1
这可能并不复杂,但为什么要仅仅为了这个简单的任务使用一个31kB的库呢?对我来说,几百字节的纯JS更加简洁 :) - goto-bus-stop
@Madcoder。如果你正在使用占位符,那么你正在使用HTML5。 - ANeves

-1

刚刚从上面获取了代码并将其更加通用化

<script type="text/javascript">


function addPlaceHolder(input) {

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

    addPlaceHolder($(':text'));
    addPlaceHolder($('textarea'));

</script>

原帖指出他不想使用jQuery。 - Scott

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