转自来源 : http://www.ifrans.cn/placehoder/

跨浏览器的placeholder – 原生JS版

html5为input元素新增了一个属性”placeholder”,提供对输入字段预期值的提示信息,input为空且未获得焦点时显示,获得焦点时消失,非常实用。目前,大部分现代浏览器都对placeholder属性提供了支持,IE10也是支持的。如果需要使IE6~IE9等浏览器支持placeholder,只有借助js了。

在这些不支持原生placeholder属性的浏览器下,通常使用value值来模拟,如果input为空且未获得焦点,就把value值设置为placeholder属性的值,一旦获得焦点,则将该input的值清空。这种方式在一些情况下会有问题,比如type=”password”的input的value值是以星号显示的,无法直接显示文字,除非同时更改type类型。再如,会给表单验证带来麻烦,如果某input是必填的,那么提交表单的时候该input的value为空或者为placeholder值时都不应该被提交,所以我们要增加对value为placeholder的判断,或许这不是什么大问题,不过如果项目里使用了验证插件,而插件本身又不支持这种方式,还是会带来些麻烦的。我在前不久的项目中就遇到了这个问题。现在重写了placeholder函数,在支持传统的使用value模拟placeholder方式的同时,提供了一种插入一个覆盖在input上的span标签来模拟placeholder的方式,可供必要时选择。先上demo:

【点击这里查看 “跨浏览器的placeholder” DEMO】

下面是js代码主要部分,全部代码就不贴出了,可以查看demo页面的源码。稍后放出jquery插件版的。

主要JS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
 * @name placeHolder
 * @class 跨浏览器placeHolder,对于不支持原生placeHolder的浏览器,通过value或插入span元素两种方案模拟
 * @param {Object} obj 要应用placeHolder的表单元素对象
 * @param {Boolean} span 是否采用悬浮的span元素方式来模拟placeHolder,默认值false,默认使用value方式模拟
 */
function placeHolder(obj, span) {
    if (!obj.getAttribute('placeholder')) return;
    var imitateMode = span === true ? true: false;
    var supportPlaceholder = 'placeholder' in document.createElement('input');
    if (!supportPlaceholder) {
        var defaultValue = obj.getAttribute('placeholder');
        if (!imitateMode) {
            obj.onfocus = function() { (obj.value == defaultValue) && (obj.value = '');
                obj.style.color = '';
            }
            obj.onblur = function() {
                if (obj.value == defaultValue) {
                    obj.style.color = '';
                } else if (obj.value == '') {
                    obj.value = defaultValue;
                    obj.style.color = '#ACA899';
                }
            }
            obj.onblur();
        } else {
            var placeHolderCont = document.createTextNode(defaultValue);
            var oWrapper = document.createElement('span');
            oWrapper.style.cssText = 'position:absolute; color:#ACA899; display:inline-block; overflow:hidden;';
            oWrapper.className = 'wrap-placeholder';
            oWrapper.style.fontFamily = getStyle(obj, 'fontFamily');
            oWrapper.style.fontSize = getStyle(obj, 'fontSize');
            oWrapper.style.marginLeft = parseInt(getStyle(obj, 'marginLeft')) ? parseInt(getStyle(obj, 'marginLeft')) + 3 + 'px': 3 + 'px';
            oWrapper.style.marginTop = parseInt(getStyle(obj, 'marginTop')) ? getStyle(obj, 'marginTop') : 1 + 'px';
            oWrapper.style.paddingLeft = getStyle(obj, 'paddingLeft');
            oWrapper.style.width = obj.offsetWidth - parseInt(getStyle(obj, 'marginLeft')) + 'px';
            oWrapper.style.height = obj.offsetHeight + 'px';
            oWrapper.style.lineHeight = obj.nodeName.toLowerCase() == 'textarea' ? '': obj.offsetHeight + 'px';
            oWrapper.appendChild(placeHolderCont);
            obj.parentNode.insertBefore(oWrapper, obj);
            oWrapper.onclick = function() {
                obj.focus();
            }
            //绑定input或onpropertychange事件
            if (typeof(obj.oninput) == 'object') {
                obj.addEventListener("input", changeHandler, false);
            } else {
                obj.onpropertychange = changeHandler;
            }
            function changeHandler() {
                oWrapper.style.display = obj.value != '' ? 'none': 'inline-block';
            }
            /**
                 * @name getStyle
                 * @class 获取样式
                 * @param {Object} obj 要获取样式的对象
                 * @param {String} styleName 要获取的样式名
                 */
            function getStyle(obj, styleName) {
                var oStyle = null;
                if (obj.currentStyle) oStyle = obj.currentStyle[styleName];
                else if (window.getComputedStyle) oStyle = window.getComputedStyle(obj, null)[styleName];
                return oStyle;
            }
        }
    }
}

-----------------------------------------------------------------------------------------------

根据上面的东东, 简单的一个demo如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="gb2312" />
    <title>跨浏览器placehoder</title>
    <meta name="author" content="ifrans.cn" />
    <meta name="description" content="跨浏览器的placehoder原生js版,让ie也支持placehoder" />
    <meta name="keywords" content="跨浏览器,placehoder,ie,原生js,表单" />
    <script type="text/javascript" src="./placeholder.js" ></script>

    <style>
        input{ vertical-align:middle; margin-left:10px; height:24px; line-height:24px; width:200px; padding-left:2px; }
        textarea{ vertical-align:middle; margin-left:10px; width:200px; height:50px; font:inherit; padding-left:2px;}
    </style>
</head>
<body onload="initPlaceholder('form1')">
<form id="form1">
    <h3>在不支持placeholder的浏览器下,通过插入悬浮的span元素方式模拟</h3>
    <p><label for="username1">用户名:</label><input type="text" name="username1" id="username1" placeholder="请输入用户名" value="" required></p>
    <p><label for="password1">密 码:</label><input type="password" name="password1" id="password1" placeholder="请输入密码" value="" required></p>
    <p><label for="address1">地 址:</label><input type="text" name="address1" id="address1" placeholder="请输入地址" value="" required></p>
    <p><label for="remarks1">备 注:</label><textarea placeholder="请输入备注" id="remarks1"></textarea></p>
</form>

</body>
</html>
/**
 * @name placeHolder
 * @class 跨浏览器placeHolder,对于不支持原生placeHolder的浏览器,通过value或插入span元素两种方案模拟
 * @param {Object} obj 要应用placeHolder的表单元素对象
 * @param {Boolean} span 是否采用悬浮的span元素方式来模拟placeHolder,默认值false,默认使用value方式模拟
 */
function placeHolder(obj, span) {
    if (!obj.getAttribute('placeholder')) return;
    var imitateMode = span===true?true:false;
    var supportPlaceholder = 'placeholder' in document.createElement('input');
    if (!supportPlaceholder) {
        var defaultValue = obj.getAttribute('placeholder');
        if (!imitateMode) {
            obj.onfocus = function () {
                (obj.value == defaultValue) && (obj.value = '');
                obj.style.color = '';
            }
            obj.onblur = function () {
                if (obj.value == defaultValue) {
                    obj.style.color = '';
                } else if (obj.value == '') {
                    obj.value = defaultValue;
                    obj.style.color = '#ACA899';
                }
            }
            obj.onblur();
        } else {
            var placeHolderCont = document.createTextNode(defaultValue);
            var oWrapper = document.createElement('span');
            oWrapper.style.cssText = 'position:absolute; color:#ACA899; display:inline-block; overflow:hidden;';
            oWrapper.className = 'wrap-placeholder';
            oWrapper.style.fontFamily = getStyle(obj, 'fontFamily');
            oWrapper.style.fontSize = getStyle(obj, 'fontSize');
            oWrapper.style.marginLeft = parseInt(getStyle(obj, 'marginLeft')) ? parseInt(getStyle(obj, 'marginLeft')) + 3 + 'px' : 3 + 'px';
            oWrapper.style.marginTop = parseInt(getStyle(obj, 'marginTop')) ? getStyle(obj, 'marginTop'): 1 + 'px';
            oWrapper.style.paddingLeft = getStyle(obj, 'paddingLeft');
            oWrapper.style.width = obj.offsetWidth - parseInt(getStyle(obj, 'marginLeft')) + 'px';
            oWrapper.style.height = obj.offsetHeight + 'px';
            oWrapper.style.lineHeight = obj.nodeName.toLowerCase()=='textarea'? '':obj.offsetHeight + 'px';
            oWrapper.appendChild(placeHolderCont);
            obj.parentNode.insertBefore(oWrapper, obj);
            oWrapper.onclick = function () {
                obj.focus();
            }
            //绑定input或onpropertychange事件
            if (typeof(obj.oninput)=='object') {
                obj.addEventListener("input", changeHandler, false);
            } else {
                obj.onpropertychange = changeHandler;
            }
            function changeHandler() {
                oWrapper.style.display = obj.value != '' ? 'none' : 'inline-block';
            }
            /**
             * @name getStyle
             * @class 获取样式
             * @param {Object} obj 要获取样式的对象
             * @param {String} styleName 要获取的样式名
             */
            function getStyle(obj, styleName) {
                var oStyle = null;
                if (obj.currentStyle)
                    oStyle = obj.currentStyle[styleName];
                else if (window.getComputedStyle)
                    oStyle = window.getComputedStyle(obj, null)[styleName];
                return oStyle;
            }
        }
    }
}

/**
 * 初始化, 对所有的input ,textarea应用. 在 body的onload中调用.
 */
function initPlaceholder(formid, doc) {
    if (!doc){ doc = document; }

    var oForm1 = doc.getElementById(formid);
    var oForm1Inputs = oForm1.getElementsByTagName('input');
    for(var i=0;i<oForm1Inputs.length;i++){
        placeHolder(oForm1Inputs[i],true);
    }
    var oForm1Textarea = oForm1.getElementsByTagName('textarea');
    for(var i=0;i<oForm1Textarea.length;i++){
        placeHolder(oForm1Textarea[i],true);
    }
}

跨浏览器的placeholder – 原生JS版的更多相关文章

  1. 跨浏览器实现placeholder效果的jQuery插件

    曾经遇到这样一个问题,处理IE8密码框placeholder属性兼容性.几经周折,这个方案是可以解决问题的. 1.jsp页面引入js插件 <script type="text/java ...

  2. 【前端】跨浏览器事件处理程序EventUtil.js个人注释及详解

    <javascript高级程序设计>跨浏览器事件处理程序EventUtil.js个人注释 EventUtil.js // 跨浏览器事件处理程序封装 var EventUtil = { // ...

  3. 原生JS版和jQuery 版实现文件上传功能

    <!doctype html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

  4. AJAX初识(原生JS版AJAX和Jquery版AJAX)

    一.什么是JSON 1.介绍 JSON独立于语言,是一种与语言无关的数据格式. JSON指的是JavaScript对象表示法(JavaScript Object Notation) JSON是轻量级的 ...

  5. 原生js版分页插件

    之前我在自己的博客里发表了一篇用angularJs自定义指令实现的分页插件,今天简单改造了一下,改成了原生JavaScript版本的分页插件,可以自定义一些简单配置,特此记录下来.如有不足之处,欢迎指 ...

  6. 封装环形加载进度条(Vue插件版和原生js版)

    1.效果预览 2.用到的知识 主要利用SVG的stroke-dasharray和stroke-dashoffset这两个属性. 在看下面文章之前,你需要了解 <!DOCTYPE html> ...

  7. 【原】运动版的轮播图,有左右按钮和单独分页,原生JS版

    运动版的轮播图,有左右按钮和单独分页 这个例子重点在于: 运动框架的复习,要灵活运动回调函数 始终以全局变量iNum来控制oUl的移动目的地,每次有任何动作,都是先判断iNum并改变iNum后去调用运 ...

  8. 如何写一个跨浏览器的事件处理程序 js

    如何 写一个合格的事件处理程序,看如下代码: EventUtil可以直接拿去用 不谢 <!DOCTYPE html> <html> <head> <title ...

  9. 原生js版ajax请求

    function getXMLHttpRequest() { var xhr; if(window.ActiveXObject) { xhr= new ActiveXObject("Micr ...

随机推荐

  1. winform WebBrowser控件中,cs后台代码执行动态生成的js

    很多文章都是好介绍C# 后台cs和js如何交互,cs调用js方法(js方法必须是页面上存在的,已经定义好的),js调用cs方法, 但如果想用cs里面执行动态生成的js代码,如何实现呢? 思路大致是这样 ...

  2. Eclipse中Maven的配置

    Maven 的配置 1. 安装配置Maven: 1.1 从Apache网站 http://maven.apache.org/ 下载并且解压缩安装Apache Maven 1.2 配置 Maven 的c ...

  3. 利用WHID为隔离主机建立隐秘通道

    0 引言 从2014年BADUSB出现以后,USB-HID攻击就这一直被关注,且具争议.争议的焦点是USB-HID的实战效果过于“鸡肋”,无论从早期的BADUSB,还是到后来的各种USB-HID设备, ...

  4. linux ls 命令

    ls 命令是 Linux 下最常用的命令之一,用来查询目录下的内容(list directory contents).本文将介绍其基本的用法和一些典型的用例.笔者使用的测试环境为 ubuntu 16. ...

  5. 百行go代码构建p2p聊天室

    百行go代码构建p2p聊天室 百行go代码构建p2p聊天室 1. 上手使用 2. whisper 原理 3. 源码解读 3.1 参数说明 3.1 连接主节点 3.2 我的标识 3.2 配置我的节点 3 ...

  6. 【C#多线程编程实战笔记】二、 线程同步

    使用Mutex类-互斥锁 owned为true,互斥锁的初始状态就是被主线程所获取,否则处于未获取状态 name为定义的互斥锁名称,在整个操作系统只有一个命名未CSharpThreadingCookb ...

  7. 关于小程序http请求的问题

    解决wx.request 发起的是 HTTPS 请求的问题 对于wx.request,大家可以理解为是微信小程序版的ajax,基于安全性考虑他的url地址必须是以https开头的,但对于一个开发者来说 ...

  8. Unity黑巧克力 滚球游戏 入门级教程

    <黑巧克力>系列教程是适合于新手上手Unity的教程,本教程适合作为初次接触Unity(零基础)的第一篇的教程.学习本教程需要有的基础是:线性代数.编程基础.Csharp语言基础.Unit ...

  9. 【集美大学1411_助教博客】团队作业2——需求分析&原型设计 成绩

    首先要向各位同学道歉,最近助教的工作较多,并且伴随着频繁的出差,评论博客和评分都不及时,以致于同学们都没有得到反馈,在此我要表示歉意.其次,对于第二次团队作业,有两个团队没有提交到班级博客中但按时完成 ...

  10. 团队作业4---第一次项目冲刺(ALpha版本)第一天

    一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 1.界面 完成登录界面 2.功能 完成数据结构设计及数据交互模块代码 完成爬虫博客页面数据采集模块 四.困难与问题 1.因为要 ...