zepto_core

   1 var Zepto = (function(){
   2     var undefined, key, $, classList, 
   3         emptyArray = [], 
   4         concat = emptyArray.concat,
   5         //[].filter(callback [, thisArg] );
   6         filter = emptyArray.filter, 
   7         //slice 数组的拷贝
   8         slice = emptyArray.slice, 
   9         document = window.document,
  10         elementDisplay = {},
  11         classCase = {},
  12         cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,
  13             'opacity': 1, 'z-index': 1, 'zoom': 1 },
  14 
  15         fragmentRE = /^\s*<(\w+|!)[^>]*>/, //匹配<a href="www.baidu.com" xxx>
  16         singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, //匹配的单个标签
  17         //非(标签里)
  18         tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
  19         rootNodeRE = /^(?:body|html)$/i,
  20         capitalRE = /([A-Z])/g,
  21 
  22         methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
  23         adjacencyOperators = ['after', 'prepend', 'before', 'append'],
  24         table = document.createElement('table'),
  25         tableRow = document.createElement('tr'),
  26         containers = {
  27             'tr': document.createElement('tbody'),
  28             'tbody': table, 'thead': table, 'tfoot': table,
  29             'td': tableRow, 'th': tableRow,
  30             '*': docuemnt.createElement('div')
  31 
  32         },
  33 
  34         readyRE = /complete|loaded|interactive/,
  35         simpleSelectorRE = /^[\w-]*$/,
  36         classw2type = {},
  37         toString = class2type.toString,
  38         zepto = {},
  39         camelize, uning,
  40         tempParent = document.createElement('div'),
  41         propMap = {
  42             'tabindex': 'tabIndex',
  43             'readonly': 'readOnly',
  44             'for': 'htmlFor',
  45             'class': 'className',
  46             'maxlength': 'maxLength',
  47             'cellspacinng': 'cellSpacing',
  48             'cellpadding': 'cellPadding',
  49             'rowspan': 'rowspan',
  50             'usemap': 'useMap',
  51             'frameborder': 'frameBorder',
  52             'contenteditable': 'contentEditable'
  53         },
  54 
  55         isArray = Array.isArray || function( obj ){
  56             return obj instanceof Array;
  57         };
  58 
  59 
  60     zepto.matches = function( element, selector ){
  61         if( !selector || !element || !elment.nodeType !== 1 ){
  62             return false;
  63         }
  64 
  65         var matchesSelecotr = element.webkitMatchesSelector || element.mozMatchesSelector ||
  66                             element.oMatchesSelector || element.matchesSelecotr;
  67 
  68         if( matchesSelecotr ){
  69             return matchesSelector.call( element, selector );
  70         }
  71 
  72         // fall back to performing a selector:
  73         var match, parent = element.parentNode, temp = !parent;
  74 
  75         if( temp ){
  76             //没有父节点
  77             (parent = tempParent).appendChild( element );
  78         }
  79 
  80         //how to implement it?
  81         match = ~zepto.qsa( parent, selector ).indexOf( element );
  82         temp && tempParent.removeChild( element );
  83         return match;
  84     }
  85 
  86     //获取参数的类型 {'[object Object]':'objct'}
  87     function type( obj ){
  88         return obj == null ? String( obj ) :
  89             class2typep[toString.call( obj ) ] || 'object'; 
  90     }
  91 
  92     function isFunction( valuue ){
  93         return type( value ) === 'function';
  94     }
  95 
  96     function isWindow( obj ){
  97         return obj != null && obj == obj.window;
  98     }
  99 
 100     function isDocument( obj ){
 101         return obj != null && obj.nodeType === obj.DOCUMENT_NODE;
 102     }
 103 
 104     function isObject( obj ){
 105         return type( obj ) == 'object';
 106     }
 107 
 108     function isPlainObject( obj ){
 109         return isObject( obj ) && !isWindow( obj ) && Object.getPrototypeOf( obj ) == Object.prototype;
 110         };
 111     }
 112 
 113     function likeArray( obj ){
 114         return typeof obj.length === 'number';
 115     }
 116 
 117     //过滤空元素
 118     function compact( array ){
 119         return filter.call( array, function( item ){
 120             return item != null;
 121         });
 122     }
 123 
 124     //concat...
 125     function flatten( array ){
 126         return array.length > 0 ? $.fn.concat.apply( [], array ) : array ;
 127     }
 128 
 129     //-(-..)a ->-(-..)A.
 130     camelize = function( str ){
 131         return str.replace( /-+(.)?)/g, function( match, chr ){
 132             return chr ? char.toUpperCase() : '';
 133         }
 134     };
 135 
 136 
 137     //::---> /   
 138     function dasherize( str ){
 139         return str.replace( /::/g, '/')
 140                 .replace(/([A-Z]+)([A-Z)[a-z]/g, '$1_$2')
 141                 .replace(/([a-z\d])([A-Z])/g, '$1_$2')
 142                 .replace(/_/g, '-')
 143                 .toLowerCase();
 144     }
 145 
 146     //剔除掉重复的元素
 147     uniq = function( array ){
 148         return filter.call( array, function( item, idx ){
 149             return array.indexOf( item ) == idx ;
 150         });
 151     };
 152 
 153     //存储RegExp对象到classCache对象上.
 154     function classRE( name ){
 155         return name in classCache ?
 156             classCache[ name ] : ( classCache[ name ] = new RegExp('(^|\\s)' + name + '(\\s|$)') );
 157     }
 158 
 159 
 160     //非cssNuber对象上的属性,为数值时,带上 'px'
 161     function maybeAddPx( name, value ){
 162         return ( typeof value === 'number' && !cssNumber[dasherize(name)] ) ? value + 'px' : value;
 163     }
 164 
 165     //
 166     function defaultDisplay( nodeName ){
 167         var element, display;
 168 
 169         if( !elementDisplay[ nodeName ] ){
 170             element = document.createElement( nodeName );
 171             document.body.appendChild( element );
 172             display = getComputedStyle( element, '' ).getPropertyValue('display');
 173             element.parentNode.removeChild( element );
 174             display == 'none' && ( display = 'block' );
 175             elementDisplay[ nodeName ] = display;
 176         }
 177 
 178         return elementDisplay[ nodeName ];
 179     }
 180 
 181     //转换成数组,并返回
 182     function children( element ){
 183         return 'children' in element ?
 184             slice.call( element.children ) :
 185             $.map( element.childNodes, function( node ){ 
 186                 if( node.nodeType == 1 ){
 187                     return node;
 188                 }
 189             } );
 190     }
 191 
 192     function Z( dom, selector ){
 193         var i, len = dom ? dom.length : 0;
 194         for( i = 0; i < len; i++ ){
 195             this[ i ] = dom[ i ];
 196         }
 197         this.selector = selector || '';
 198     }
 199 
 200     /*
 201         
 202     */
 203     zepto.fragment = function( html, name, properties ){
 204         var dom, nodes, conntainer;
 205 
 206         //<a ></a> <input /> 
 207          if( singleTagRE.test( html ) ){
 208             dom = $(document.createElement( RegExp.$1 ) );
 209         }
 210 
 211         if( !dom ){
 212             //将$1,$2 填充成<X></X>
 213             if( html.replace ) html = html.replace( tagExpanderRE, "<$1></$2>" );
 214 
 215             if( name === undefined ) name = fragmentRE.test( html ) && RegExp.$1;
 216 
 217             if( !(name in containers ) ) name = '*';
 218             //取个包装元素
 219             container = containers[ name ];
 220             container.innerHTML = '' + html;
 221             dom = $.each( slice.call( container.childNodes ), function(){
 222                 container.removeChild( this );  // 返回container里子元素
 223             });
 224         }
 225 
 226         //是对象的话
 227         if( isPlainObject( properties ) ){
 228             nodes = $(dom);
 229             $.each(properties, funnction( key, value ){
 230                 if(methodAttributes.indexOf( key ) > -1 ){
 231                     nodes[ key ]( value );  //对象css赋值
 232                 }else{
 233                     nodes.attr( key, value ); //将值挂到对象上
 234                 }
 235             });
 236         }
 237 
 238         return dom;
 239     }
 240 
 241     //
 242     zepto.Z = function( dom, selector ){
 243         return new Z( dom, selector );
 244     }
 245 
 246     zepto.isZ = function( object ){
 247         return object instanceof zepto.Z;
 248     }
 249 
 250     //
 251     zepto.init = function( selector, context ){
 252         var dom;
 253 
 254         if( !selector ) {
 255             return zepto.Z();
 256         } else if(typeof selector === 'string' ) {
 257             selector = selector.trim();
 258 
 259             if( selector[ 0 ] == '<' && fragmentRE.test( selector ) ){
 260                 dom = zepto.fragment( selector, RegExp.$1, context);
 261                 selector = null;
 262             } else if( context !== undefined ){
 263                 return $(context).find( selector );
 264             }else {
 265                 dom = zepto.qsa( document, selector );
 266             }
 267 
 268         }else if( isFunction( selector ) ){
 269             return $(document).ready( selector );
 270         }else if( zepto.isZ( selector ) ){
 271             return selector;
 272         }else{
 273             if( isArray(selector) ){
 274                 dom = compact( selector );
 275             }else if( isObject( selector ) ){
 276                 dom = [ selector ], selector = null;
 277             }else if( fragmentRE.test( selector ) ){
 278                 dom = zepto.fragment( selector.trim() , RegExp.$1, context );
 279                 selector = null;
 280             }else if( context !== undefined ){
 281                 return $(context).find( selector );
 282             }else{
 283                 dom = zepto.qsa( document, selector );
 284             }
 285         }
 286         //返回 Z(dom, selector)
 287         return zepto.Z( dom, selector );
 288     }
 289 
 290     //调用的zepto.init...
 291     $ = function( selector, context ){
 292         return zepto.init( selector, context );
 293     }
 294 
 295     //私有方法, 扩展属性
 296     function extend( target, source, deep ){
 297         for( key in source ){
 298             if( deep && (isPlainObject(source[key] ) || isArray( source[key]) ) ){
 299                 if( isPlainObject(source[key]) && !isPlainObject( target[key] ) ){
 300                     target[ key ] = {};
 301                 }
 302                 if( isArray(source[key]) && !isArray( target[key]) ){
 303                     target[ key ] = [];
 304                 }
 305 
 306                 extend( target[ key ], source[key], deep );
 307             }else if( source[key] !== undefined ){
 308                 target[ key ] = source[key];
 309             }
 310         }
 311     }
 312 
 313     // may be  target is boolean   arguments[1] is really target object.
 314     $.extend = function( target ){
 315         var deep, args = slice.call( arguments, 1 );
 316         if( typeof target === 'boolean' ){
 317             deep = target;
 318             target = args.shift();
 319         }
 320 
 321         args.forEach( function( arg ){ extend( target, arg, deep )} );
 322 
 323         return target;
 324     }
 325 
 326     //高版本浏览器 qsa查询元素
 327     zepto.qsa = function( element, selector ){
 328         var found, 
 329             maybeID = selector[ 0 ] == '#',
 330             maybeClass = !maybeID && selector[ 0 ] == '.',
 331             nameOnly = maybeID || maybeClass ? selector.slice( 1 ) : selector ,
 332             isSimple = simpleSelectorRE.test( nameOnly );
 333 
 334         return ( element.getElementById && isSimple && maybeId ) ?
 335             (( found = element.getElementById( nameOnly ) ) ? [ found ] : []) :
 336             ( element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11 ) ? [] :
 337             slice.call( 
 338                 isSimple && !maybeId && element.getElementsByClassName ?
 339                     maybeClass ? element.getElementsByClassName( nameOnly ) :
 340                     element.getElementsByTagName( selector ) :
 341                     element.querySelectorAll( selector );
 342             );
 343 
 344     };
 345 
 346     //筛选元素通过selector
 347     function filtered( node, selector ){
 348         return selector == null ? $(nodes) : $(nodes).filter( selector )
 349     };
 350 
 351     //给$对象,挂上 contains函数
 352     $.contains = document.documentElement.contains ?
 353         function( parent, node ){
 354             return parent !== node && parent.contains( node ); 
 355         } :
 356         function( parent, node ){
 357             while( node && ( node = node.parentNode ) ){
 358                 if( node === parent )
 359                     return true;
 360             }
 361             return false;
 362         };
 363 
 364      //如果 arg是对象的话,那么给arg绑定执行上下文的 this 对象
 365     function funcArg( context, arg, idx, payload ){
 366         return isFunction( arg ) ? arg.call( context, idx, payload ) : arg;
 367     };
 368 
 369     //取值,或设置
 370     function className( node, value ){
 371         var klass = node.className || '',
 372             svg = klass && klass.baseVal !== undefined;
 373 
 374         if( value === undefined ) 
 375             return svg ? klass.baseVal : klass 
 376         svg ? ( klass.baseVal = value ) : ( node.className = value );
 377     }
 378 
 379 
 380     /*
 381         'true'-> true
 382         'false'-> false
 383         'null' -> null
 384         '42'-> 42
 385         '08'->'08'
 386         JSON-> parse if valid
 387         string-> self
 388     */
 389     //将数据转化
 390     function deserializeValue( value ){
 391         try{
 392             return value ?
 393                 value == 'true' ||
 394                     ( value == 'false') ? false :
 395                       value == 'null' ? null :
 396                       +value + "" == value ? +value :
 397                       /^[\[\{]/.test(value) ? $.parseJSON( value ) :
 398                           value )
 399                     : value;
 400         } catch( e ){
 401             return value;
 402         }
 403     }
 404 
 405     $.type = type;
 406     $.isFunction  = isFunction;
 407     $.isArray = isArray;
 408     $.isPlainObject = isPlainObject;
 409     
 410     //判断是否为空对象,
 411     $.isEmptyObject = function( obj ){
 412         var name;
 413         for( name in obj ) return false;
 414         return true;
 415     }
 416 
 417     //从 i 处 开始搜索 下标
 418     $.inArray = function( elem, array, i ){
 419         return emptyArray.indexOf.call( array, elem, i );
 420     }
 421 
 422     $.camelCase = camelize;
 423     $.trim = function( str ){
 424         return str == null ? "" : String.prototype.trim.call( str );
 425     }
 426 
 427     $.uuid = 0;
 428     $.support = {};
 429     $.expr = {};
 430     $.noop = function(){};
 431 
 432     $.map = function( elements, callback ){
 433         var value, values = [], i, key;
 434         //如果是类数组的话,那么就映射,
 435         if( likeArray( elements ) ){
 436             for( i = 0; i < elements.length; i++ ){
 437                 value = callback( elements[i], i );
 438                 if( value != null ){
 439                     values.push( value );
 440                 }
 441             }
 442         } else {
 443             //是对象的话,那么遍历对象,调用callback映射
 444             for( key in elements ){
 445                 value = callback( elements[ kye ], key );
 446                 if( value != null ){
 447                     values.push( value );
 448                 }
 449             }
 450         }
 451 
 452         return flatten( values );
 453     }
 454 
 455     $.each = function( elements, callback ){
 456         var i, key;
 457 
 458         if( likeArray( elements ) ){
 459             for( i = 0; i < elements.length; i++ ){
 460                 if( callback.call( elements[ i ], i, elements[i] ) === false ){
 461                     return elements;
 462                 }
 463             }
 464         } else {
 465             for( key in elements ){
 466                 if( callback.call( elements[ key ], key, elements[ key ]) === false )
 467                     return elements;
 468             }
 469         }
 470     };
 471 
 472     $.grep = function( elements, callback ){
 473         return filter.call( elements, callback );
 474     };
 475 
 476     if( window.JSON ) $.parseJSON = JSON.parse;
 477 
 478     $.each("Boolean Number String Function Array Data RegExp Object Error".split(" "), function( i, name ){
 479         class2type[ '[objct ' + name + ']' ] = name.toLowerCase();
 480     });
 481 
 482     //原型函数是绑定了this执行上下文。
 483     $.fn = {
 484         constructor : zepto.Z,   // 将原型函数的构造函数指向  zepto.Z
 485         length = 0,
 486 
 487         forEach: emptyArray.forEach,
 488         reduce: emptyArray.reduce,
 489         push: emptyArray.push,
 490         sort: emptyArray.sort,
 491         splice: emptyArray.splice,
 492         indexOf: emptyArray.indexOf,
 493         concat: function(){
 494             var i, value, args = [];
 495             for( i = 0; i < arguments.lengtjh; i++ ){
 496                 value = arguments[ i ];
 497                 args[ i ] = zepto.isZ( value ) ? value.toArray() : value;
 498             }
 499 
 500             return concat.apply( zepto.isZ(this) ? this.toArray() : this, args );
 501         },
 502 
 503         map: function( fn ){
 504             return $( $.map(this, function( el, i ){
 505                 return fn.call( el, i, el );
 506             }) );
 507         },
 508 
 509         slice: function(){
 510             return $( slice.apply( this, arguments ) );
 511         },
 512 
 513         ready: function( callback ){
 514             if( readyRE.test( document.readyState ) && document.body ){
 515                 callback( $ );
 516             } else {
 517                 document.addEventListener( 'DOMContentLoaded', function(){
 518                     callback( $ );
 519                 }, false );
 520             }
 521 
 522             return this;
 523         },
 524 
 525         get: function( idx ){
 526             return idx === undefined ? slice.call( this ) : this[ idx >= 0 ? idx : idx + this.length ];
 527         },
 528 
 529         toArray: function(){ return this.get() },
 530         size: function(){
 531             return this.length;
 532         },
 533 
 534         remove: function(){
 535             return this.each(function(){
 536                 if( this.parentNode != null ){
 537                     this.parentNode.removeChild( this );
 538                 }
 539             });
 540         },
 541 
 542         each: function( callback ){
 543             emptyArray.every.call( this, function( el, idx ){
 544                 return callback.call( el, idx, el ) !== false;
 545             });
 546 
 547             return this;
 548         },
 549 
 550         filter: function( selector ){
 551             if( isFunction( selector ) ){
 552                 return this.not( this.not( selector ) );
 553             }
 554 
 555             return $( filter.call( this, function(){
 556                 return zepto.matches( element, selector );
 557             }) );
 558         },
 559 
 560         add: function( selector, context ){
 561             return $(uniq(this.concat( $(slector, context) )));
 562         },
 563 
 564         is: function( selector ){
 565             return this.length > 0 && zepto.matches( this[ 0 ], selector );
 566         },
 567 
 568         not: function( selector ){
 569             var nodes = [];
 570 
 571             if( isFunction( selector ) && selector.call !== undefined ){
 572                 this.each( function( idx ){ 
 573                     if( !selector.call( this, idx ) ){
 574                         nodes.push( this );;
 575                     }
 576                 });
 577             } else {
 578                 var excludes = typeof selector === 'string' ? this.filter( selector ) :
 579                     ( likeArray( selector ) && isFunction( selector.item ) ) ?  slice.call( selector ) : $(selector);
 580 
 581                 this.forEach( function( el ){
 582                     if( excludes.indexOf( el ) < 0 ){
 583                         nodes.push( el );
 584                     }
 585                 })
 586             }
 587 
 588             return $(nodes);
 589         },
 590 
 591         has: function( selector ){
 592             return this.filter(function(){
 593                 return isObject( selector ) ? 
 594                     $.contains( this, selector ) :
 595                     $(this).find( selector ).size();
 596             });
 597         },
 598 
 599         eq: function( idx ){
 600             return idx === -1 ? this.slice( idx ) : this.slice( idx, + idx + 1 ) ;
 601         },
 602 
 603         first: function(){
 604             var el = this[ 0 ];
 605             return el && !isObject( el ) ? el : $(el);
 606         },
 607 
 608         last: function(){
 609             var el = this[ this.length - 1 ];
 610             return el && !isObject( el ) ? el : $(el);
 611         },
 612 
 613         find: function( selector ){
 614             var result, $this = this;
 615             if( !selector ){
 616                 result = $();
 617             } else if( typeof selector == 'object' ){
 618                 result = $(selector).filter( function(){
 619                     var node = this;
 620                     return emptyArray.some.call( $this, function( parent ){
 621                         return $.contains(parent, node);
 622                     });
 623                 });
 624             } else if( this.length == 1 ){
 625                 result = $(zepto.qsa(this[0], selector));
 626             } else {
 627                 result = this.map( function(){
 628                     return zepto.qsa( this, selector );
 629                 });
 630             }
 631 
 632             return result;
 633         },
 634 
 635         closest: function( selector, context ){
 636             var node = this[ 0 ],  collection = false;
 637             if( typeof selector == 'object' ) collection = $(selector);
 638             while( node && !(collection ? collection.indexOf( node ) >= 0 zepto.matches(node, selector )))
 639                 node = node !== context && !isDocument( node ) && node.parentNode;
 640             return $(node);
 641         },
 642 
 643         parents: function( selector ){
 644             var ancestors = [], nodes = this;
 645             while( nodes.length > 0 ){
 646                 nodes = $.map( nodes, function( node ){
 647                     if((node = node.parentNode) && !isDocument( node ) && ancestors.indexOf(node) < 0 ){
 648                         ancestors.push( node );
 649                         return node;
 650                     }
 651                 });
 652             }
 653             return filtered( ancestors, selector );
 654         },
 655 
 656         parent: function( selector ){
 657             return filtered( uniq( this.pluck('parentNode')), selector );
 658         },
 659 
 660         children: function( selector ){
 661             return filtered( this.map( function(){ return children(this) }), selector );
 662         },
 663 
 664         contents: function(){
 665             return this.map( function(){ return this.contentDocument || slice.call(this.childNodes ) });
 666         },
 667 
 668         siblings: function(){
 669             return filtered( this.map(function(i,el){
 670                 return filter.call( children(el.parentNode), function(child){ return child !== el });
 671             }));
 672         },
 673 
 674         empty: function(){
 675             return this.each( function(){this.innerHTML = '' });
 676         },
 677 
 678         pluck: function( property ){
 679             return $.map(this, function(el){ return el[property] };)
 680         },
 681 
 682         show: function(){
 683             return this.each( function(){
 684                 this.style.display == 'none' && (this.style.display = '');
 685 
 686                 if( getComputedStyle(this, '').getPropertyValue( 'display' ) == 'none' ){
 687                     this.style.display = defaultDisplay( this.nodeName );
 688                 }
 689             });
 690         },
 691 
 692         replaceWith: function( newContent ){
 693             return this.before( newContent ).remove();
 694         },
 695 
 696         wrap: function( structure ){
 697             var func = isFunction( structure );
 698 
 699             if( this[ 0 ] && !func ){
 700                 var dom = $(structure).get( 0 ),
 701                     clone = dom.parentNode || this.length > 1;
 702 
 703                 return this.each( function( index ){
 704                     $(this).wrapAll(
 705                         func ? structure.call( this, index ) :
 706                             clone ? dom.cloneNode( true ) : dom;
 707                     );
 708                 });
 709             }
 710         },
 711 
 712         wrapAll: function( structure ){
 713             if( this[ 0 ] ){
 714                 $(this[0]).before(structrue = $(structure) );
 715                 var children;
 716                 while( ( children = structure.children() ).length )
 717                     structure = children.first();
 718                 $(structure).append( this );;
 719             }
 720 
 721             return this;
 722         },
 723 
 724         wrapInner: function( structure ){
 725             var func = isFunction( structure );
 726             return this.each( function(index){
 727                 var self = $(this), contents = self.contents(),
 728                     dom = func ? structure.call(this, index) : structure;
 729                 contents.length ? contents.wrapAll( dom ) : self.append( dom );
 730             });
 731         },
 732 
 733         unwrap: function(){
 734             this.parent().each(function(){
 735                 $(this).replaceWith( $(this).children() );
 736             });
 737 
 738             return this;
 739         },
 740 
 741         clone: function(){
 742             return this.map( function(){return this.cloneNode(true)} );
 743         },
 744 
 745         hide: function(){
 746             return this.css("display", 'none');
 747         },
 748 
 749         toggle: function( setting ){
 750             return this.each(function(){
 751                 var el = $(this);
 752                 (setting === undefined ? el.css('display') == 'none' : seeting) ? el.show() : el.hide();
 753             });
 754         },
 755 
 756         prev: function( selector ){
 757             return $(this.pluck('previousElementSibling')).filter( slector || '*' );
 758         },
 759         next: function( select ){
 760             return $(this.pluck('nextElementSibling')).filter( selector || '*' );
 761         },
 762         html: function( html ){
 763             return 0 in argumennts ?
 764                 this.each( function(idx){
 765                     var originHtml = this.innerHTML;
 766                     $(this).empty().append( funcArg(this,html, idx, originHtml) )
 767                 }) :
 768                 ( 0 in this ? this[0].innerHTML : null );
 769 
 770         },
 771 
 772         text: function( text ){
 773             return 0 in arguments ?
 774                 this.each(function(idx){
 775                     var newText = funcArg(this, text, idx, this.textContent );
 776                     this.textContent = newText == null ? '' : '' + newText;
 777                 }) :
 778                 ( 0 in this ? this.pluck('textContent').join("") : null );
 779         },
 780 
 781         attr: function( name, value ){
 782             return ( typeof name === 'string' && !(1 in arguments)) ?
 783                 (!this.length || this[0].nodeType !== 1 ? undefined :
 784                     (!(result = this[0].getAttribute(name) ) && name in this[0]) ? this[0][name] : result 
 785             ) :
 786             this.each( function( idx ){
 787                 if( this.nodeType !== 1) return;
 788                 if( isObject(name) ) for( key in name ) setAttribute( this, key, name[key] );
 789                 else setAttribute( this, name, funcArg(this, value, idx, this.getAttribute(name) ));
 790             });
 791         },
 792 
 793         removeAttr: function( name ){
 794             return this.each(function(){
 795                 this.nodeType === 1 && name.split(' ').forEach(function(attribute){
 796                     setAttribute(this, attribute);
 797                 }, this);
 798             })
 799         },
 800 
 801         prop: function( name, value ){
 802             name = propMap[ name ] || name;
 803             return (1 in arguments ) ?
 804                 this.each( function(idx){
 805                     this[name] = funcArg( this, value, idx, this[name] );
 806                 }) :
 807                 ( this[0] && this[0][name]);
 808          },
 809 
 810          data: function( name, value ){
 811              var attrName = 'data-' + name.replace(capitalRE,'-$1').toLowerCase();
 812 
 813              var data = (1 in arguments) ?
 814                  this.attr(attrName, value) :
 815                  this.attr(attrName);
 816 
 817              return data !== null ? deserializeValue( data ) : undefined;
 818          },
 819 
 820          val: function(value){
 821              return 0 in arguments ?
 822                  this.each(function(idx){
 823                      this.value = funcArg( this, value, idx, this.value );
 824                  }) :
 825                  ( this[0] && (this[0].multiple ?
 826                      $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
 827                      this[0].value;
 828                  ));
 829          },
 830 
 831          offset: function( coordinates ){
 832              if( coordinates )return this.each(function(index){
 833                  var $this = $(this),
 834                      coords = funcArg(this, coordinates, index, $this.offset() ),
 835                      parentOffset = $this.offsetParent().offset(),
 836                      props = {
 837                          top: coords.top - parentOffset.top,
 838                          left: coords.left - parentOffset.left
 839                      };
 840 
 841                  if($this.css('position') == 'static') props['prosition'] = 'relative';
 842                  $this.css(props);
 843              });
 844 
 845              if( !this.length ) return null;
 846              if( !$.contains(document.documentElement, this[0]) )
 847                  return {top: 0, left: 0};
 848              var obj = this[0].getBoundingClientRect() 
 849              return {
 850                  left: obj.left + window.pageXOffset,
 851                  top: obj.top + window.pageYOffset,
 852                  width: Math.round( obj.width ),
 853                  height: Math.round( obj.height )
 854              }; 
 855          },
 856 
 857          css: function( property, value ){
 858              if( arguments.length < 2 ){
 859                  var computedStyle, element = this[0];
 860                  if( !element ) return;
 861                  computedStyle = getComputedStyle(element, '');
 862                  if( typeof property == 'string' ){
 863                      return element.style[camelize(property)] || computedStyle.getPropertyValue( prop );
 864                  } else if( isArray( property ) ){
 865                      var props = {};
 866                      $.each(property, function(_,prop){
 867                          props[ prop ] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop));
 868                      });
 869 
 870                      return props;
 871                  }
 872              }
 873 
 874              var css = '';
 875              if( type(property) == 'string' ){
 876                  if( !value && value !== 0 ){
 877                      this.each( function(){ this.stye.removeProperty( dasherize(property) ) });
 878                  } else {
 879                      css = desherize(property) + ":" + maybeAddPx(property, value);
 880                  }
 881              } else {
 882                  for( key in property ){
 883                      if( !property[ key ] && property[ key ] !== 0 ){
 884                          this.each( function(){ this.style.removeProperty(dasherize(key)) });
 885                      } else {
 886                          css += dasherize( key ) + ":" + maybeAddPx(key, property[key] ) + ";"
 887                      }
 888                  }
 889              }
 890 
 891              return this.each( function(){ this.style.cssText += ';' + css });
 892          },
 893 
 894          index: function( element ){
 895              return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf( this[0] );
 896          },
 897 
 898          hasClass: function( name ){
 899              if( !name ) return false;
 900              return emptyArray.some.call( this, function( el ){ 
 901                  return this.test( className(el) );
 902              }, classRE(name) );
 903          },
 904          
 905          addClass: function( name ){
 906              if( !name ) return this;
 907              return this.each(function( idx ){
 908                  if( !('className') in this ) return;
 909                  classList = [];
 910                  var cls = className( this ), 
 911                      newName = funcArg(this, name, idx, cls );
 912                  newName.split(/\s+/g).forEach(function(klass){
 913                      if( !$(this).hasClass(klass) ) classList.push( klass );
 914 
 915                  }, this);
 916                  classList.length && className( this, cls + (cls ? " " : "") + classList.join( " "));
 917              });
 918          },
 919 
 920          removeClass: function( name ){
 921              return this.each( function(idx)P{
 922                  if( !('className' in this ) ) return;
 923                  if( name === undefined ) return className(this, '');
 924                  classList = className(this);
 925                  funcArg( this, name, idx, classList )
 926                      .split(/\s+/g).forEach(function(klass){
 927                          classList = classList.replace(classRE(klass), " ");
 928                      });
 929                  className( this, classList.trim() );
 930               });
 931          },
 932 
 933          toggleClass: function( name, when ){
 934              if( !name ) return this;
 935              return this.each(function(idx){
 936                  var $this = $(this), 
 937                      names = funcArg( this, name, idx, className( this ) );
 938 
 939                  names.split(/\s+/g).forEach(function(klass){
 940                      (when === undefiend ? !$this.hasClass(klass) : when )?
 941                          $this.addClass(klass) : $this.removeClass(klass);
 942                  });
 943              });
 944          },
 945 
 946          scrollTop: function( value ){
 947              if( !this.length ) return;
 948              var hasScrollTop = 'scrollTop' in this[0] ;
 949              if( value === undefined ) return hasScrollTop ? this[0].scrollTo : this[0].pageYOffset;
 950              return this.each( hasScrollTop ?
 951                  function(){ this.scrollTop = value } :
 952                  function(){ this.scrollTo(this.scrollX, value); });
 953          },
 954 
 955          scrollLeft: function( value ){
 956              if( !this.length ) return;
 957              var hasScrollLeft = 'scrollLeft' in this[0];
 958              if( value === undefined ) 
 959                  return hasScrollLeft ?  this[0].scrollLeft : this[0].pageXOffset;
 960              return this.each(hasScrollLeft ?
 961                  function(){ this.scrollLeft = value } :
 962                  function(){ this.scrollTo(value, this.scrollY) });
 963          },
 964 
 965          position: function(){
 966              if( !this.length ) return;
 967 
 968              var elem = this[0],
 969                  offsetParent = this.offsetParent(),
 970 
 971                  offset = this.offset(),
 972                  parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ?
 973                       { top: 0, left: 0 } : offsetParent.offset();
 974 
 975              offset.top  -= parseFloat( $(elem).css('margin-top') ) || 0;
 976              offset.left -= parseFloat( $(elem).css('margin-left') ) || 0;
 977 
 978              parentOffset.top += parsetFloat( $(offsetParent[0]).css('border-top-width') ) || 0;
 979              parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0;
 980 
 981              return {
 982                  top: offset.top - parentOffset.top,
 983                  left: offset.lefft - parentOffset.left
 984              }      
 985          },
 986 
 987          offsetParent: function(){
 988              return this.map( function(){
 989                  var parent = this.offsetParent || document.body;
 990                  while( parent && !rootNodeRE.test(parent.nodeName) && $(parent).css('position') == 'static')
 991                      parent = parent.offsetParent;
 992                  return parent;
 993              });
 994          },
 995 
 996          $.fn.detach = $.fn.remove;
 997 
 998          ;['width', 'height'].forEach(function(dimension){
 999              var offset, el = this[0];
1000              if( value === undefined )
1001                  return iwWindow( el ) ? el['inner' + dimensionProperty] : 
1002                      isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
1003                      (offset = this.offset()) && offset[dimension];
1004              else 
1005                  return this.each( function(idx){
1006                      el = $(this);
1007                      el.css(dimension, funcArg(this, value, idx, el[dimension]() ));
1008                  });
1009          });
1010 
1011          function traverseNode( node, fun ){
1012              fun(node);
1013              for( var i = 0, len = node.childNodes.length; i < len; i++ ){
1014                  traverseNode(node.childNodes[i], fun );
1015              }
1016          },
1017 
1018       adjacencyOperators.forEach(function(operator, operatorIndex) {
1019         var inside = operatorIndex % 2 //=> prepend, append
1020 
1021         $.fn[operator] = function(){
1022           // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
1023           var argType, nodes = $.map(arguments, function(arg) {
1024                 argType = type(arg)
1025                 return argType == "object" || argType == "array" || arg == null ?
1026                   arg : zepto.fragment(arg)
1027               }),
1028               parent, copyByClone = this.length > 1
1029           if (nodes.length < 1) return this
1030 
1031           return this.each(function(_, target){
1032             parent = inside ? target : target.parentNode
1033 
1034             // convert all methods to a "before" operation
1035             target = operatorIndex == 0 ? target.nextSibling :
1036                      operatorIndex == 1 ? target.firstChild :
1037                      operatorIndex == 2 ? target :
1038                      null
1039 
1040             var parentInDocument = $.contains(document.documentElement, parent)
1041 
1042             nodes.forEach(function(node){
1043               if (copyByClone) node = node.cloneNode(true)
1044               else if (!parent) return $(node).remove()
1045 
1046               parent.insertBefore(node, target)
1047               if (parentInDocument) traverseNode(node, function(el){
1048                 if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
1049                    (!el.type || el.type === 'text/javascript') && !el.src)
1050                   window['eval'].call(window, el.innerHTML)
1051               })
1052             })
1053           })
1054         }
1055 
1056         // after    => insertAfter
1057         // prepend  => prependTo
1058         // before   => insertBefore
1059         // append   => appendTo
1060         $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
1061           $(html)[operator](this)
1062           return this
1063         }
1064       });
1065 
1066       zepto.Z.prototype = Z.prototype = $.fn;
1067 
1068       zepto.uniq = uniq;
1069 
1070       zepto.deserializeValue = deserializeValue;
1071       $.zepto = zepto;
1072 
1073       return $;
1074     }
1075 })();
1076 
1077 window.Zepto = Zepto;
1078 window.$ === undefined && (window.$ = Zepto );
View Code

 

posted @ 2016-02-26 06:41  Olive_branch  阅读(233)  评论(0编辑  收藏  举报