/recx

这个javascript组件,记录用户在页面上的输入和选择,当用户下一次载入该页面时,还原上次的输入和选择。进而达到降低用户成本,提高用户体验的目的。

Primary LanguageJavaScript

recx.js

这个javascript组件,记录用户在页面上的输入和选择,当用户下一次载入该页面时,还原上次的输入和选择。进而达到降低用户成本,提高用户体验的目的。

具体说来,它能记录用户对下拉菜单 <select> 、单选按钮 <input type="radio"> 、选择框 <input type="checkbox"> 的选择及各种输入框 <input>,type不为"radio"、"checkbox"、"submit"、"button"、"hidden"、"image"、"file"或"reset"、输入区域 <textarea> 的值,并在用户下次载入页面时,按照上次记录的值还原用户的选择及输入的值。

支持的浏览器如下,也就是说,目前还在广泛使用的浏览器中,只有IE6\IE7\IE8不支持:

  • IE 9+
  • Firefox 3+
  • Safari 3.2+
  • chrome 5+
  • iOS 3.2+
  • Android 2.1+

如何使用?

快速上手

在你HTML代码的尾部引入recx.js:

<script src="recx.js"></script>

或者使用AMD、CMD、Kissy兼容的模块加载器:

require(['recx'],function(recx){
	// your code 
})

接着你为所有要记录的“下拉菜单 <select> 、单选按钮 <input type="radio"> 、选择框 <input type="checkbox"> 的选择及各种输入框 <input>,type不为"radio"、"checkbox"、"submit"、"button"、"hidden"、"image"、"file"或"reset"、输入区域 <textarea> ”(我们称它为“可交互元素”,下同)均赋予一个 id,如:

<input id="checkbox_0" type="checkbox"/>

然后加入下面一句代码,即可记录页面中所有区域内上述元素的选择或输入值:

recx()

高级

指定记录的区域

入口函数recx(wrapperDOM)的第一个参数 wrapperDOM 可以是某个dom元素,或某个dom元素的id的字符串。 可以通过传递需要记录的区域的最外层dom元素或它的id,来指定需要记录的区域:

recx('wrapper') // 这将记录id为`wrapper`的dom元素内部的所有符合要求的“可交互元素”
// 或 recx(document.getElementById('wrapper'))

如果要指定记录页面中的多个区域,则通过调用多次使用 recx(),传递不同的 wrapperDOM 参数来实现: 注意:不能指定已被指定过的的wrapperDOM,或是一个与已被指定过的的wrapperDOM有包含或被包含的关系的dom

recx('area1')
recx('area2') // area2与area1不能有包含和被包含关系(即任意一个不能为另一个的父、子节点)

甚至可以将区域限制小到只有某一个“可交互元素”:

// html:
<input id="input_0" />
// js:
<script>
	recx('input_0') // 指定记录的区域仅为id为`input_0`的input本身
</script>

注意:在这种情况下,你不能只指定区域为:一组关联的(name值相同的)单选按钮 <input type="radio"> 中的一个,因为这一组单选按钮共同来决定一个值,只记录其中一个是没有意义的

// html:
<p id="radioGroupP">
	radio group:<br/>
	<input id="radio_0" type="radio" name="my_radio" value="value_0">
	<input id="radio_1" type="radio" name="my_radio" value="value_1">
</p>
// js:
<script>
	recx('radio_1') // 反例,这是不对的,没有意义
	recx('radioGroupP') // 这是对的,因为所有`name`相同的单选按钮都被包裹进去了
</script>

不记录页面中的某些“可交互元素”

最简单的方法就是不为这些“可交互元素”赋予id,或者将它们的id通过下面的方式加入到忽略id数组。 注意:对于一组关联的(name值相同的)单选按钮 <input type="radio"> ,你需要将它们每一个 <input> 的id都添加进去,或者给每一个 <input> 都不赋予id

recx(document,{
    ignoreIds:['select_0','radio_0','radio_1']
})

自行控制下一次页面载入时“可交互元素”的还原行为

默认情况下,在下一次载入页面时,该组件会将所有符合要求且未被忽略的“可交互元素”赋予上一次的值,你也可以获取这个值来进行其它操作。通过配置一个函数的形式来操作它。如果该配置函数返回true,则继续执行组件原本的设定值操作;如果函数返回值为false,则不继续执行组件原本的设定值操作

recx(document,{
	handleSetValueFromCacheFuncs:{
    	'input_0':function(value,wrapperDOM){
        	// this 指向当前dom,本例中即id为input_0的元素
        	// value 当前存储值,如果this是一个<textarea>,请用recx.configs.textareaLineFeedHolder替换回换行符,如value.replace(recx.configs.textareaLineFeedHolder,'\n')
        	//  如果this是一个<input type="radio">,并且它没有指定value值,那么可以通过recx.configs.noValueRadioIndexPrefix获取在所有name相同的<input type="radio">中它的位置,如 value.replace(recx.configs.noValueRadioIndexPrefix,'')
        	//  如果this是一个<input type="checkbox">,并且它没有指定value值,如果他被选中了(this.checked),那么value为1,否则为0
        	// wrapperDOM是初始化时,传入的wrapperDOM参数对应的dom
        	return true // 继续执行组件原本的设定值操作
        	// return false // 不继续执行组件原本的设定值操作
    	}
	}
})

修改全局默认配置

可以通过修改recx.configs静态方法来修改默认配置。 请注意,需要先修改默认配置,再初始化recx对象实例。

// 修改示例:
recx.customConfig({
	oldValueAttributeName:'data-recxoldvalue'
})

可以修改的默认配置:

字段名 默认值 说明
noValueRadioIndexPrefix '__R_NVRIP__' 有一组 name 值相同的 <input type="radio"> ,但当前被选中的radio可能没有 value 值,我们就要一个模拟的值——用它在这一组radio中的位置来代替它的值来存储。noValueRadioIndexPrefix就是这个假值的前缀。举个例子:如果第三个radio被选中了,我们将noValueRadioIndexPrefix+'3',默认配置下即__R_NVRIP__2当做模拟值来存储
oldValueAttributeName 'data-roldvalue' <input>,type不为"radio"和"checkbox"textarea 必须将旧值存储起来,以便于检查值是否发生了变化。我们将旧制存储到这个dom属性中
textareaLineFeedHolder '__R_TLFH_ramdom_769768842_ramdom_' textarea的换行符会在与其他字符串连接时丢弃。为了避免这种情况,我们在这之前用这个属性的值将换行符替换到。在还原时再替换回来
getLocalStorageKeySuffix 一个函数,详见源码 对于某个站点的不同页面,用于在localStorage里面存储用户交互值的key是不相同的。这个函数用于根据location对象计算出这个key。默认情况下,我们对于单页应用(OPOA,或称为SPA)考虑了location.hash部分,对于传统的后端渲染的前端页面,没有考虑location.hash部分。可以重写这个函数,函数的参数是location对象

在AMD|CMD|Kissy体系中修改全局默认配置

在AMD体系中,由于不清楚recx.js是否已经被加载和配置过,我们建议您将配置项也写成一个AMD模块,例如:

// 假设路径为 js/recxConfig.js
define({
	oldValueAttributeName:'data-recxoldvalue'
})

在每次使用recx时

require(['recx','js/recxConfig'],function(recx,recxConfig){
	recx.customConfig(recxConfig)
	// do sth.
})

这样能确保只用书写一处配置文件。或者也可以直接修改源代码里24行的configs

详细接口

recx对象实例 每当你调用recx()时,如果没有报错,它都会返回一个recx的对象实例,这个对象实例能让你做进一步精细的控制。

wrapperDom属性

指向当前recx对象实例的wrapperDom,即使你初始化时的wrapperDom参数传递的是dom的id,也会指向实际的dom。当初始化时传递的wrapperDom参数不合法,则指向document

handleSetValueFromCacheFuncs属性

指向当前recx对象实例初始化时配置项里面的handleSetValueFromCacheFuncs对象,如果未设置或不合法,则为 {}

ignoreIds属性

指向当前recx对象实例初始化时配置项里面的ignoreIds数组,如果未设置或不合法,则为 []

selects属性

一般情况下,指向当前recx对象实例wrapperDom内的所有select元素的 HTMLCollection,当wrapperDom本身即为一个select时,指向只包含该select的长度为1的数组

textareas属性

一般情况下,指向当前recx对象实例wrapperDom内的所有textarea元素的 HTMLCollection,当wrapperDom本身即为一个textarea时,指向只包含该textarea的长度为1的数组

inputs属性

一般情况下,指向当前recx对象实例wrapperDom内的所有input元素的 HTMLCollection,当wrapperDom本身即为一个input时,指向只包含该input的长度为1的数组;注意,inputs里面可能包含recx组件不关注类型的input(即type为"radio"、"checkbox"、"submit"、"button"、"hidden"、"image"、"file"或"reset"的input)

setValue方法

var myrecx = recx(wrapperDom,settings)
myrecx.setValue()

这个方法会在调用入口函数recx(),生成recx对象实例时自动调用一次。它的作用是将缓存储的上一次“可交互元素”的值设置到对应“可交互元素”上。 你也可以在适当的时候手动调用它,这样它会把该recx对象实例所包含的“可交互元素”再次赋值一遍。

getKvObj方法

var myrecx = recx(wrapperDom,settings)
myrecx.getKvObj()

这个方法返回当前wrapperDom内所有满足监听条件的“可交互元素”的id和当前值。对象结构为:

{
	id1:value1,
	id2:value2
}

stop方法

var myrecx = recx(wrapperDom,settings)
myrecx.stop()

这个方法将会注销掉recx对象,使他不再起任何作用。比如注销掉对对应“可交互元素”的监听。

License

所有代码遵循 "MIT License":http://www.opensource.org/licenses/mit-license.php 。也就是说你可以自由地做任何你想做的事情。只是不能在代码中移除我的名字。