用JavaScript解决Placeholder的IE8兼容问题

placeholder属性是HTML5新添加的属性,当input或者textarea设置了该属性后,该值的内容将作为灰色提示显示在文本框中,当文本框获得焦点时,提示文字消失,placeholder可作为输入框的提示文案

placeholder是常用的属性,它使得input框内有很友好的提示效果。高版本浏览器都支持placeholder属性,但IE9以下版本的浏览器并不支持这一属性。这里用JavaScript实现添加对浏览器的兼容处理。

方案一:jquery实现

(当浏览器不支持placeholder属性时,克隆一个和界面相同的input框,将placeholder的值设置为其value值,覆盖在界面input框所在位置,并将界面上的input隐藏掉)

 调用方法: $(#selector).placeholder();(selector泛指css 的 id选择器)

(这里有一个问题,当文本框type=password时,引用此placeholder方案会使暗文密码变成明文密码)

;(function(window, document, $) {

    // Opera Mini v7 doesn’t support placeholder although its DOM seems to indicate so
    var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]';
    var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini;
    var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini;
    var prototype = $.fn;
    var valHooks = $.valHooks;
    var propHooks = $.propHooks;
    var hooks;
    var placeholder;

    if (isInputSupported && isTextareaSupported) {

        placeholder = prototype.placeholder = function() {
            return this;
        };

        placeholder.input = placeholder.textarea = true;

    } else {

        placeholder = prototype.placeholder = function() {
            var $this = this;
            $this
                .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]')
                .not('.placeholder')
                .bind({
                    'focus.placeholder': clearPlaceholder,
                    'blur.placeholder': setPlaceholder
                })
                .data('placeholder-enabled', true)
                .trigger('blur.placeholder');
            return $this;
        };

        placeholder.input = isInputSupported;
        placeholder.textarea = isTextareaSupported;

        hooks = {
            'get': function(element) {
                var $element = $(element);

                var $passwordInput = $element.data('placeholder-password');
                if ($passwordInput) {
                    return $passwordInput[0].value;
                }

                return $element.data('placeholder-enabled') && $element.hasClass('placeholder') ? '' : element.value;
            },
            'set': function(element, value) {
                var $element = $(element);

                var $passwordInput = $element.data('placeholder-password');
                if ($passwordInput) {
                    return $passwordInput[0].value = value;
                }

                if (!$element.data('placeholder-enabled')) {
                    return element.value = value;
                }
                if (value == '') {
                    element.value = value;
                    // Issue #56: Setting the placeholder causes problems if the element continues to have focus.
                    if (element != safeActiveElement()) {
                        // We can't use `triggerHandler` here because of dummy text/password inputs :(
                        setPlaceholder.call(element);
                    }
                } else if ($element.hasClass('placeholder')) {
                    clearPlaceholder.call(element, true, value) || (element.value = value);
                } else {
                    element.value = value;
                }
                // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363
                return $element;
            }
        };

        if (!isInputSupported) {
            valHooks.input = hooks;
            propHooks.value = hooks;
        }
        if (!isTextareaSupported) {
            valHooks.textarea = hooks;
            propHooks.value = hooks;
        }

        $(function() {
            // Look for forms
            $(document).delegate('form', 'submit.placeholder', function() {
                // Clear the placeholder values so they don't get submitted
                var $inputs = $('.placeholder', this).each(clearPlaceholder);
                setTimeout(function() {
                    $inputs.each(setPlaceholder);
                }, 10);
            });
        });

        // Clear placeholder values upon page reload
        $(window).bind('beforeunload.placeholder', function() {
            $('.placeholder').each(function() {
                this.value = '';
            });
        });

    }

    function args(elem) {
        // Return an object of element attributes
        var newAttrs = {};
        var rinlinejQuery = /^jQuery\d+$/;
        $.each(elem.attributes, function(i, attr) {
            if (attr.specified && !rinlinejQuery.test(attr.name)) {
                newAttrs[attr.name] = attr.value;
            }
        });
        return newAttrs;
    }

    function clearPlaceholder(event, value) {
        var input = this;
        var $input = $(input);
        if (input.value == $input.attr('placeholder') && $input.hasClass('placeholder')) {
            if ($input.data('placeholder-password')) {
                $input = $input.hide().next().show().attr('id', $input.removeAttr('id').data('placeholder-id'));
                // If `clearPlaceholder` was called from `$.valHooks.input.set`
                if (event === true) {
                    return $input[0].value = value;
                }
                $input.focus();
            } else {
                input.value = '';
                $input.removeClass('placeholder');
                input == safeActiveElement() && input.select();
            }
        }
    }

    function setPlaceholder() {
        var $replacement;
        var input = this;
        var $input = $(input);
        var id = this.id;
        if (input.value == '') {
            if (input.type == 'password') {
                if (!$input.data('placeholder-textinput')) {
                    try {
                        $replacement = $input.clone().attr({ 'type': 'text' });
                    } catch(e) {
                        $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' }));
                    }
                    $replacement
                        .removeAttr('name')
                        .data({
                            'placeholder-password': $input,
                            'placeholder-id': id
                        })
                        .bind('focus.placeholder', clearPlaceholder);
                    $input
                        .data({
                            'placeholder-textinput': $replacement,
                            'placeholder-id': id
                        })
                        .before($replacement);
                }
                $input = $input.removeAttr('id').hide().prev().attr('id', id).show();
                // Note: `$input[0] != input` now!
            }
            $input.addClass('placeholder');
            $input[0].value = $input.attr('placeholder');
        } else {
            $input.removeClass('placeholder');
        }
    }

    function safeActiveElement() {
        // Avoid IE9 `document.activeElement` of death
        // https://github.com/mathiasbynens/jquery-placeholder/pull/99
        try {
            return document.activeElement;
        } catch (exception) {}
    }

}(this, document, jQuery));

方案二: js/jQuery实现

实现思路:

1、首先判断浏览器是否支持placeholder属性,如果不支持则使用模拟placeholder

2、创建一个label标签:<label>密码</label> 标签里面的内容为所要添加的提示文字,该文字应该从对应的input|textarea标签取得其placeholder属性值,再将label标签遮盖 到所对应的input|textarea上

3、代码实现如下:

; (function (win) {

    win.isPlaceholer = function () {
        var input = document.createElement("input");
        return "placeholder" in input;
    };
  
    win.placeholder = function () {

        if (!isPlaceholer()) {
            var Placeholder =function (obj) {
                this.input = obj;
                var te = obj.getAttribute('placeholder');
                this.label = document.createElement('label');
                this.label.innerHTML = te;
                this.label.id = obj.id + 'Label';
                this.label.style.cssText = 'position:absolute; text-indent:4px;color:#999999; font-size:14px;';
                if (obj.value !== '') {
                    this.label.style.display = 'none';
                }
                this.init();
            };
            Placeholder.prototype = {

                getxy: function (obj) {
                    var left, top;
                    if (document.documentElement.getBoundingClientRect) {
                        var html = document.documentElement,
                        body = document.body,
                        pos = obj.getBoundingClientRect(),
                        st = html.scrollTop || body.scrollTop,
                        sl = html.scrollLeft || body.scrollLeft,
                        ct = html.clientTop || body.clientTop,
                        cl = html.clientLeft || body.clientLeft;
                        left = pos.left + sl - cl;
                        top = pos.top + st - ct;
                    } else {
                        while (obj) {
                            left += obj.offsetLeft;
                            top += obj.offsetTop;
                            obj = obj.offsetParent;
                        }
                    }
                    return {
                        left: left,
                        top: top
                    };
                },

                getwh: function (obj) {
                    return {
                        w: obj.offsetWidth,
                        h: obj.offsetHeight
                    };
                },

                setStyles: function (obj, styles) {
                    for (var p in styles) {
                        obj.style[p] = styles[p] + 'px';
                    }
                },
                init: function () {
                    var label = this.label,
                    input = this.input,
                    getXY = this.getxy,
                    xy = this.getxy(input),
                    wh = this.getwh(input);
                    this.setStyles(label, { 'width': wh.w, 'height': wh.h, 'lineHeight': 40, 'left': xy.left + 8, 'top': xy.top });
                    document.body.appendChild(label);
                    label.onclick = function () {
                        this.style.display = "none";
                        input.focus();
                    };
                    input.onfocus = function () {
                        label.style.display = "none";
                    };
                    input.onblur = function () {
                        if (this.value === "") {
                            label.style.display = "block";
                        }
                    };
                    if (window.attachEvent) {
                        window.attachEvent("onresize", function () {
                            var xy = getXY(input);
                            Placeholder.prototype.setStyles(label, { 'left': xy.left + 8, 'top': xy.top });
                        });
                    } else {
                        window.addEventListener("resize", function () {
                            var xy = getXY(input);
                            Placeholder.prototype.setStyles(label, { 'left': xy.left + 8, 'top': xy.top });
                        }, false);
                    }
                }
            };

            var inpColl = $("#Box input:visible");//这里是页面上要添加placeholder支持的input
            //var inpColl = document.getElementsByTagName('input'),          
            var textColl = document.getElementsByTagName('textarea');//这里是页面上要添加placeholder支持的textarea
            //var lableArr = $("#Box lable");
            var toArray = function (coll) {
                for (var i = 0, a = [], len = coll.length; i < len; i++) {
                    a[i] = coll[i];
                }
                return a;
            };
            var inpArr = toArray(inpColl),
            textArr = toArray(textColl),

            placeholderArr = inpArr.concat(textArr);
            for (var i = 0; i < placeholderArr.length; i++) {
                if (placeholderArr[i].getAttribute('placeholder') !== null) {

                    new Placeholder(placeholderArr[i]);
                }
            }
        }

    };
}(window));

方法执行后界面代码:(lable在页面上)

IE8效果图如下:

原文:http://www.cnblogs.com/meggie523/p/5067774.html



除了上面两种方式,还发现下面这段代码也是可以的,我在公司项目中用的就是下面这段,测试可用

// 兼容IE8,IE9下placeholder属性
if (!('placeholder' in document.createElement('input'))) {
    $('input[placeholder],textarea[placeholder]').each(function() {
        var that = $(this),
            text = that.attr('placeholder');
        if (that.val() === "") {
            that.val(text).addClass('placeholder');
        }
        that.focus(function() {
            if (that.val() === text) {
                that.val("").removeClass('placeholder');
            }
        }).blur(function() {
            if (that.val() === "") {
                that.val(text).addClass('placeholder');
            }
        }).closest('form').submit(function() {
            if (that.val() === text) {
                that.val('');
            }
        });
    });
}


相关阅读

jquery.placeholder.min.js让IE浏览器支持placeholder属性

赞(52) 打赏
未经允许不得转载:优客志 » 前端设计
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏