mass Framework data模块 v3
这是吸收jquery2.0的新技术,通过节点在数组中的索引值来关联目标与缓存体。这就有效避开了IE下某些节点不能添加自定义属性的问题,也在es5中新增的Object.preventExtensions方法下得以生存。
//================================================== // 数据缓存模块 //================================================== define("data", ["$lang"], function( $ ){ function Data(user) { this.owners = []; this.user = user; this.cache = []; } Data.prototype = { add: function( owner ) { var index = this.owners.push( owner ); return (this.cache[ index - 1 ] = {}); }, access: function( owner, key, value ) { var index = this.owners.indexOf( owner ); var cache = index === -1 ? this.add( owner ) : this.cache[ index ]; if(typeof key == "string"){ if(value == undefined){//读方法 //对于用HTML5 data-*属性保存的数据, 如<input id="test" data-full-name="Planet Earth"/> //我们可以通过$("#test").data("full-name")或$("#test").data("fullName")访问到 if(this.user && !(key in cache) && owner && owner.nodeType == 1 ){ $.parseData( owner, key, cache ); } return cache[key]; }else{ return cache[key] = value;//写方法 } } return key && typeof key == "object" ? $.mix(cache, value) : cache; }, remove: function( owner, key ) { var name, camel = $.String.camelize, index = this.owners.indexOf( owner ), cache = this.cache[ index ]; if ( key === undefined ) { cache = {}; } else { if ( cache ) {//如果已经存在 if ( !Array.isArray( key ) ) { //如果不是数组 if ( key in cache ) { name = [ key ]; } else {//尝试驼峰化再求,再不行数组化 name = camel( key ); name = name in cache ? [ name ] : name.match($.rword); } } else {//如果是数组 name = key.concat( key.map( camel ) ); } for (var i =0, l = name.length ; i < l; i++ ) { delete cache[ name[i] ]; } } } this.cache[ index ] = cache; }, hasData: function( owner ) { var index = this.owners.indexOf( owner ); if ( index > -1 ) { return !$.isEmptyObject( this.cache[ index ] ); } return false; } }; var user = new Data(true), priv = new Data; $.mix( { data: function( elem, name, data ) { return user.access( elem, name, data ); }, removeData: function( elem, name ) { return user.remove( elem, name ); }, _data: function( elem, name, data ) { return priv.access( elem, name, data ); }, _removeData: function( elem, name ) { return priv.remove( elem, name ); }, hasData: function( elem ) { return user.hasData( elem ) || priv.hasData( elem ); }, parseData: function(target, name, cache, value){ var data, key = $.String.camelize(name),_eval if(cache && (key in cache)) return cache[key]; if(arguments.length != 4){ var attr = "data-" + name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); value = target.getAttribute( attr ); } if ( typeof value === "string") {//转换 /^(?:\{.*\}|null|false|true|NaN)$/ if(/^(?:\{.*\}|\[.*\]|null|false|true|NaN)$/.test(value) || +value + "" === value){ _eval = true } try { data = _eval ? eval("0,"+ value ) : value } catch( e ) { data = value } if(cache){ cache[ key ] = data } } return data; }, //合并数据 mergeData: function( cur, src){ if( priv.hasData(src) ){ var oldData = priv.access(src), curData = priv.access(cur), events = oldData .events; $.Object.merge( curData , oldData ); if(events){ curData.events = []; for (var i = 0, item ; item = events[i++]; ) { $.event.bind( cur, item ); } } } if( user.hasData(src) ){ oldData = user.access(src) curData = user.access(cur) $.Object.merge( curData , oldData ); } } }); return $ });
不能不感概jQuery团队的奇思妙想。但这个新方案也不尽完美,它以是四个不断膨胀的数组为代码实现的,估计得结合1.8中昙花一现的deleteIds技术才能解决这问题。
机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年