成长脚印-专注于互联网发展
【经验】js实时触发"onchange"事件&&防止浏览器保存密码
post by:天之骄子 2013-4-10 0:59

点击查看原图

首先谈问题:

需求很简单,一个很简单的登陆页面,两个INPUT输入框(有户名,密码),都有各自的提示背景,onFocus的时候提示背景隐藏,onBlur的时候,如果INPUT的value为空则重新显示提示背景。
这种需求,实现方法很多种,最简单的就是直接设置INPUT的背景图片,也是现在用到的方法:
HTML:

<form action="" method="">
    <!--用户名-->
    <input type="text" name="username" id="username" onFocus="toggleBg(this,'in');" onBlur="toggleBg(this,'out')"> 
    <!--密码-->
    <input type="password" name="pwd" id="password" onFocus="toggleBg(this,'in');" onBlur="toggleBg(this,'out')" oninput="alert(this.value);" onpropertychange="alert(this.value)">
</form>

CSS:
    #username,#password{background-image:url(images/input_bg);}
    #username{background-position:0px 0px;}
    #password{background-position:0px -80px;}

JS:
function toggleBg(){
    …………//省略,需求上已经说出
}

问题:我们都知道在我们提交表单后浏览器都会有一个提示“是否保存密码”,当点击确认保存后,下次同样的登陆表单,双击username INPUT会显示出输入历史.

点击查看原图点击查看原图

选中我们保存的用户名后,密码输入框会自动填充为已保存的密码。于是乎就出现了这种情况:pwd INPUT并没有触发onFocus事件,所以背景图片并没有隐藏,于是密码和背景重叠出现了。。。

点击查看原图

问题解决历程:


一、Period One:     既然是浏览器自动填充造成的,那就阻止浏览器自动填充呗,讨论见[http://www.dewen.org/q/1804]。
从讨论的结果总结:

浏览器只有在如下两种情况下才会提示“是否保存密码”
    1.Form 表单提交,
    2.同时有text INPUT和password INPUT。

所以“阻止”浏览器记住密码自然就有两种方法了:
    1.不要Form表单标签(话说新浪就是这种,直接AJAX提交表单),

    2.不要password INPUT,密码输入框也用text INPUT(,,小心被别人瞧见了,隐私泄露咯,,当然可以setTimeout替换密码输入框的value为*来解决,注:INPUT的type属性是静态属性,js是无法控制更改此属性的,所以别想着onFocus的时候改变type为password)。话说,使用Period One中的方法就可以解决这个问题了。

    但:

    1.页面已提交给JAVA工程师,别人懒得用AJAX表单提交,就想省事用Form表单提交,
    2.有些用户懒得输入账户密码,就是喜欢浏览器保存密码自动填充。固,用Period One就有点儿不人性化了。


二、Period Two:     既然不能使用阻止浏览器记住密码的方法,那么只能想办法在浏览器自动填充的时候把password INPUT背景图片隐藏,于是想,自动填充的时候username INPUT或password INPUT触发的是什么事件呢?首先想到的当然是onChange事件咯,但,onChange在属性值改变时还必须使得当前元素失去焦点(onBlur)才可以激活该事件。坑爹呀,必须onBlur才能触发onChange事件。于是不能使用onChange了。。

三、Period Three:   百度谷歌大搜罗,得知 IE浏览器有个onpropertychange事件,相对于的,非IE浏览器有个oninput事件。于是问题解决了:
<input type="text" name="username" id="username" onFocus="toggleBg(this,'in');" onBlur="toggleBg(this,'out')" oninput="checkBg();" onpropertychange="checkBg()"><!--用户名-->
即:给username INPUT添加两个触发事件onpropertychange 和oninput。checkBg()函数自然是检查password INPUT背景情况咯,隐藏其背景图片,(注:不能绑定在password INPUT上,经测试点击username INPUT下拉显示的输入过的账户让密码自动填充时,password INPUT的事件onpropertychange 和oninput并没有被触发。应该是获取焦点的input才会触发如上两个事件。)
另:onpropertychange在IE6及IE6+中经测试均可触发。(网上有人说IE6不能触发onpropertychange)


COPY一段:
onchange在属性值改变时还必须使得当前元素失去焦点(onblur)才可以激活该事件。

如果你需要即时监听输入框值的变化,建议使用 onpropertychange 事件!

在IE下,当一个HTML元素的属性改变的时候,都能通过 onpropertychange来即时捕获。

在非IE浏览器可以用 oninput 事件来监听。

再补充下关于几个事件的区别:

1、onchange事件与onpropertychange事件的区别:
onchange事件在内容改变(两次内容有可能还是相等的)且失去焦点时触发;onpropertychange事件却是实时触发,即每增加或删除一个字符就会触发,通过js改变也会触发该事件,但是该事件IE专有。

2、oninput事件与onpropertychange事件的区别:
oninput事件是IE之外的大多数浏览器支持的事件,在value改变时触发,实时的,即每增加或删除一个字符就会触发,然而通过js改变value时,却不会触发;onpropertychange事件是任何属性改变都会触发的,而oninput却只在value改变时触发,oninput要通过addEventListener()来注册,onpropertychange注册方式跟一般事件一样。(此处都是指在js中动态绑定事件,以实现内容与行为分离)

3、oninput与onpropertychange失效的情况:
(1)oninput事件:a). 当脚本中改变value时,不会触发;b). 从浏览器的自动下拉提示中选取时,不会触发。

(2)onpropertychange事件:当input设置为disable=true后,onpropertychange不会触发。

 

【参考】:

oninput,onpropertychange,onchange的用法和区别

js触发onchange事件的方法

有关onpropertychange事件的一点小发现

有没有有效及简便的方法来防止浏览器记住用户名及密码?

评论:
天之骄子
2013-12-13 16:12 回复
@水多:只有填充了用户名,浏览器才会给密码框自动填充密码的(而不会在没有用户名的情况下自动填充密码),所以事件绑定在username那个输入框上。
水多
2013-12-13 09:22 回复
那就是密码还是不能在自动填充时触发事件了啊
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容