expando:生成唯一的JQ字符串(内部)
作为映射关系的,保证唯一的字符串。
expando:"jquery" + (core_version + Math.random()).replace(/\D/g, '');
alert($.expando);
noConflict() : 防止冲突
$, JQuery,命名冲突问题。
var hugo = $.noConflict();
var $ = 58; //给$复制
hugo (function () {
alert($);
})
hugo来代替$,现在$为123 noConflict: function( deep ) { //deep放弃JQuery的对外接口 if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; },
返回的值就是JQuery对象,
在上面定义过: _$ = windows.$;
$.noConflict(true); //放弃JQuery
isReady : DOM是否加载完成
$(funciton () { DOM加载完成,就开始运行
})
这里要区分window.onload和ready()方法。 onloads要等全部都加载完成,才开始运行。
DOMContentLoader原生中DOM加载的事件。
$(function() {})--->>> $(document).ready(function () {}); //这两个一样。
$.ready(); //工具方法。这两个不是一样的。
$().ready(); //这是实例方法。
jQuery.ready.promise().done( fn ); //创建的是一个延迟对象。
jQuery.ready.promise (obj) 防止外面去修改。promise只有三个状态。
if (document.readyState === 'complete') {
(1)
setTimeout(jQuery.ready); //省掉时间参数,为了解决IE的问题。
}
else {
(2)
document.addEventListener("DOMContentLoaded", complete, false);
window.addEventListener("load", complete, false);
}
(1), (2)都调用read方法。--->>>>
readyList.resolveWith(documnet, [jQuery]) //已完成!!!
---》》fn
complete是个函数,内嵌了两个removeEventListener;删除了load和DOMContentLoaded两个事件。然后调用jQuery.ready();
只会ready一次。
ODM加载事件。
延迟对象:promise状态是无法被修改的。
jQuery判断DOM是否好了,用document.readyState == 'complete'来判断。
一:
$(function(arg) {
alert(arg);
})
二:
document.ready(function () {
;
});
三:
$(document).on('ready', function () {
;
})
readyWait : 等待多少文件的计数器(内容)
holdReady() : 推迟DOM触发
$.holderReady(true); //推迟加载事件
$(function(arg) {
alert(arg);
})
$.holdReady(false); //释放
可以使用holdReady实现你想要的加载顺序
比如:
a.js
alert(1);
$.holdReady(true); //推迟加载
$.getScript('a.js', funciton () {
$.holdReady(false); //开启加载
})
$(function () {
alert(2);
});
alert顺序为1 2 。如果没有holdReady,就是2,1.
可以holdready多次。
// Hold (or release) the ready event
holdReady: function( hold ) {
if ( hold ) { //true 释放。
jQuery.readyWait++; //添加一个holdready
} else { //false 添加。
jQuery.ready( true );
}
},
ready : 准备DOM触发
ready: function( wait ) {
// Abort if there are pending holds or we're already ready
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;
}
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) { //这里看到readyWait--为0的时候,才可以继续运行。
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ jQuery ] );
// Trigger any bound ready events
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
}
工具方法的调用都要加一个$
function hg() {
}
alert($.isFunction(hg)); //true
这里注意:在低版本的IE,不会返回function类型,返回object类型。
isFunction: function( obj ) {
return jQuery.type(obj) === "function";
},
isArray() 数组
在ES5中,已经原生js判断数组的函数了。
Array.isArray()
isArray: Array.isArray,
isWindow() :是否是window对象
isWindow: function( obj ) {
return obj != null && obj === obj.window;
},
这里解释一下:alert(true == null) //false
除了 undefined == null 和 null == null 是true,其他的都是false;null和undefined没有包装对象,无法添加方法。
除了undefined和null,其他都在后面判断。 === 判断是否是类型和值都相同。
window是全局变量,或者是浏览器窗口。window.open()
isNumeric():是否是数字
isNumeric: function( obj ) {
return !isNaN( parseFloat(obj) ) && isFinite( obj );
},
前半段,判断是不是NaN
后半段,判断是否是一个有限的数字。isFinite,超出了计算机能计算的数字,就返回false; (Number.MAX_VALUE 最大值)
判断是否可以转数字,并且是一个有限的数字。
type():判断数据类型
type: function( obj ) {
if ( obj == null ) { //只有2种情况成立,就是null喝undefined。
return String( obj ); //返回字符串。
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" :
typeof obj;
},
var a = {};
alert($.type(a)); //这个比typeof要强大一些。
alert({}.toString.call([])); //object Array
alert({}.toString.call([]) == '[object Array]'); //true
alert({}.toString.call({}) == '[object Array]'); //false
alert({}.toString.call(new Date) == '[object Date]'); //true
做类型判断的时候,尽量用这个来判断。
{}.toString.call(obj); //判断obj的类型。
isPlanObject():是否为对象自变量
//判断对象自变量
//有2种形式, json 和 new Object();
var obj = { name: 'hello'};
alert($.isPlainObject(obj));
isPlainObject: function( obj ) {
//不是obj就返回,nodeType节点类型,
//将DOM节点放入jQuery中,返回Object,但是DOM节点不是对象自变量
//window也不是对象自变量
if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
//例如传入,window.location对象,jQuery也返回对象。但是又不是对象自变量。
//首先判断是否有constructor这个属性,其次,
//core_hasOwn 是hasOwnProperty。判断这个属性是不是自身的。
//isPrototypeOf是Object自己独有的属性,其他没有。
//判断属性跟原型之间的关系。
try {
if ( obj.constructor &&
!core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
return false;
}
} catch ( e ) {
return false;
}
return true;
},
//FFwindow.constructor 频繁调用,会产生泄漏。
isEmptyObject():是否为空对象
isEmptyObject: function( obj ) {
var name;
for ( name in obj ) {
return false;
}
return true;
},
var obj = [];
var a = null;
都是空。没有属性跟方法。就是空。利用了for in 完成。
for in 必须是自身下面的属性和方法,系统自带的。
比如像,constructor 这种是无法被for in 循环得到的。
error():抛出异常
error: function( msg ) {
throw new Error( msg ); //抛出自定义错误
},
$.error('这是错误');
//判处异常就是提示的。
parseHTML():解析节点
//把一个字符串转化为节点。
parseHTML: function( data, context, keepScripts ) {
if ( !data || typeof data !== "string" ) {
return null;
}
if ( typeof context === "boolean" ) {
keepScripts = context;
context = false;
}
context = context || document;
var parsed = rsingleTag.exec( data ),
scripts = !keepScripts && [];
// 看是否是单标签
if ( parsed ) {
return [ context.createElement( parsed[1] ) ];
}
//多标签,文档碎片的形式,创建,然后一次性追加入文档。
parsed = jQuery.buildFragment( [ data ], context, scripts );
//判断是否有script标签。
if ( scripts ) {
jQuery( scripts ).remove();
}
return jQuery.merge( [], parsed.childNodes ); //返回一个dom节点,用merge转成数组。--》json
},
var str = '<li></li><li></li></script>';
console.log($.parseHTML(str, document, true));
//三个参数,第一个是要解析的节点
//第二个是 父节点,一定是document
//第三个是,布尔值,是否存入sript标签
$('<li></li>') //创建一个,
//调用
$.parseHTML();
(1)单标签,就是直接createElement,
(2)多标签,就调用buildFragment。
parseJSON():字符串解析为json
注意,这个字符串一定要是一个严格Json,
parseJSON: JSON.parse,
还有一个eval,安全性上,parse比eval安全。parse是解析严格的json。
将json--》str 方法是:JSON.stringify();
这个事ES6,提供的方法,IE8以上的版本。
var str = '{"name":"hello"}';
alert($.parseJSON(str).name);
parseXML解析XML,
现在用的比较少了,用的json比较多。 parseXML: function( data ) { var xml, tmp; if ( !data || typeof data !== "string" ) { return null; } // Support: IE9 try { tmp = new DOMParser(); xml = tmp.parseFromString( data , "text/xml" ); } catch ( e ) { xml = undefined; } if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; },
noop空函数。
noop: function() {},
function test() {
this.defaluts = {
<!-- show :function() {} -->
show :$.noop
}
}
globalEval:全局解析JS,将局部变量变为全局变量。
将代码转为全局,代码是字符串
globalEval: function( code ) {
var script,
indirect = eval; //将eval变成局部变量,全局范围内可以找打
//先去掉前后空格
code = jQuery.trim( code );
//存在。
if ( code ) {
//查看是否包含严格模式。
//在严格模式下,是不支持eval解析。
//通过创建script标签来添加到head,然后在删除就可以了。
if ( code.indexOf("use strict") === 1 ) {
script = document.createElement("script");
script.text = code;
document.head.appendChild( script ).parentNode.removeChild( script );
} else
{
//直接用eval来解析。
indirect( code ); // indirect eval
//这里注意,eval和window.eval是有区别的,
}
}
},
function test() {
var newvar = true;
}
alert(newarr); //undefined;
function test() {
jQuery.globalEval(" var newvar = true;");
}
alert(newarr); //true;
<!-- 在严格模式下面。 -->
code = "var aaa = 'hgwj'";
var script = document.createElement("script");
script.text = code;
document.head.appendChild( script ).parentNode.removeChild( script );
<!-- document.head.appendChild( script ).parentNode.removeChild( script ); -->
camelCase //转驼峰
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
},
(1)IE前面有前缀,需要注意,因为IE不识别, 第一个字母大写。
-ms-transform -->> msTransform
-moz-transform -->> moz-transform.
replace( rmsPrefix, "ms-" ):目的是把 -ms转换为ms。这样解决IE问题。
replace( rdashAlpha, fcamelCase ) //转驼峰。fcamelCase是对调函数。
nodeName:是一个内部方法,是否为指定的节点名。
nodeName: function( elem, name ) {
//先判断是否有elem,然后再判断节点名称是否和name相等,
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
},
document.documentElement是html。判断这个标签是否和后面的一样。
alert($.nodeName(document.documentElement, 'HTML')); //true
alert($.nodeName(document.body, 'HTML')); //false
alert($.nodeName(document.body, 'body')); //false
alert(document.body.nodeName); //BODY
each:循环,遍历集合。
//args是内部使用的参数。
each: function( obj, callback, args ) {
var value,
i = 0,
length = obj.length, //判断是什么类型。
isArray = isArraylike( obj ); //判断是否是数组。
if ( args ) { //内部使用。
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback.apply( obj[ i ], args ); //不定参数
if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.apply( obj[ i ], args );
if ( value === false ) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else { //外部使用
if ( isArray ) { //是数组就for循环
for ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] ); //定参
if ( value === false ) {
break;
}
}
} else { //json形式,就用for in
for ( i in obj ) {
value = callback.call( obj[ i ], i, obj[ i ] );
if ( value === false ) { //通过return false控制,结束循环。
break;
}
}
}
}
return obj;
},
//使用each遍历数组
var arr = ['a', 'b', 'c'];
$.each(arr, function (key, value) {
alert(key + " " + value);
});
//使用 $.each遍历json
var json = {a:'aaa', b:'bbb', c:'ccc'};
$.each(json, function (key, value) {
alert(key + " " + value);
return false; //结束循环。
});
trim 去前后,空白。
trim: function( text ) {
return text == null ? "" : core_trim.call( text );
},
$.trim(' ht '); //ht
ES5,提供原生的trim方法。
makeArray 将类数组,转换为真正的数组。
makeArray: function( arr, results ) {
var ret = results || [];
if ( arr != null ) {
if ( isArraylike( Object(arr) ) ) {
jQuery.merge( ret, //进行合并数组
typeof arr === "string" ?
[ arr ] : arr
);
} else {
core_push.call( ret, arr );
}
}
return ret;
},
使用:
var lis = document.getElementsByTagName('li');
console.log($.makeArray(lis));
字符串Object(string); --> 转换为json
inArray : 查询数组元素,类似于indexof i是开始位置。
inArray: function( elem, arr, i ) {
return arr == null ? -1 : core_indexOf.call( arr, elem, i );
},
var arr = ['a', 'b', 'c', 'd'];
alert($.inArray('c', arr)); //2
alert($.inArray('w', arr)); //-1
merge: 合并数组
merge: function( first, second ) {
var l = second.length,
i = first.length,
j = 0;
//判断是不是number, json没有长度。
if ( typeof l === "number" ) { //没有长度,就不能走
for ( ; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i; //改变length长度。
return first;
},
if : $.merge(['a', ['b'], ['c', 'd']]);
else : $.merge(['a', 'b'], {0:"v", 1:'5'});
或者, $.merge({0:'a', 1:'b'}, {0:"v", 1:'5'});
变成: {0:, 1:....length:n};
grep:过滤得到新数组
grep: function( elems, callback, inv ) {
var retVal,
ret = [],
i = 0,
length = elems.length;
inv = !!inv; //加了2个!转换为false
for ( ; i < length; i++ ) {
retVal = !!callback( elems[ i ], i ); //返回真假, 参数是元素,和第几位。
if ( inv !== retVal ) {
ret.push( elems[ i ] );
}
}
return ret;
},
使用:
var arr = [1,2,3,4,5,6];
//grep就是将满足返回条件为true的数组元素,
arr = $.grep(arr, function (n , i) {
return n > 2;
});
console.log(arr); //[3, 4, 5, 6]
第三个参数,true,就否,就是条件的反向。
undefined !! 两次,就变成了false。
map:
map: function( elems, callback, arg ) {
var value,
i = 0,
length = elems.length,
isArray = isArraylike( elems ),
ret = [];
// Go through the array, translating each of the items to their
if ( isArray ) { //数组。
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
// Go through every key on the object,
} else {
for ( i in elems ) { //json for in
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
}
}
// 得到单一的数组,不是复合数组。
return core_concat.apply( [], ret );
},
使用:
var arr = [1,2,3,4,5,6];
//grep就是将满足返回条件为true的数组元素,
arr = $.map(arr, function (n , i) {
return n + 1;
});
console.log(arr); //[2, 3, 4, 5, 6, 7];
guid
// A global GUID counter for objects
guid: 1
guid唯一表示标识。
proxy:改变this指向。
proxy: function( fn, context ) {
var tmp, args, proxy;
//判断是否是字符串
if ( typeof context === "string" ) {
tmp = fn[ context ]; //支持简化的写法。
context = fn;
fn = tmp;
}
/*
var obj = {
show:function () {
alert(this);
}
}
$(document).click(obj.show); //this-》document
//如果想改变this,
$(document).click($proxy(obj.show, obj)); //this-》obj
简写的方式:
$(document).click($.proxy(obj, 'show')));
$.proxy(obj, 'show')-->转化为--》$.proxy(obj.show, obj);
*/
if ( !jQuery.isFunction( fn ) ) { //fn必须是函数。
return undefined;
}
args = core_slice.call( arguments, 2 ); //从第3个参数开始,
proxy = function() { //还是调用apply
//core_slice.call( arguments )转化成真正的数组。
return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
};
//生成唯一的标识。
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
return proxy;
},
使用
function show(x, y) {
alert(this);
alert(x);
alert(y);
}
//传递参数的三种方式。
$.proxy(show, document)(1, 2); //这里的this指向了document
$.proxy(show, document, 2, 4); //这里的this指向了document, 传入参数。
$.proxy(show, document, 2)(4); //这里的this指向了document, 传入参数。
access:多功能的值操作,这个要多体会。
$().css(); $().attr(); //可以获取,或者设置参数。
$('div1').css({background:'red',color:'blue', width:'200px'});
//使用在css,这种当中,判断是否是获取,还是赋值。
//fn回调函数,
//key: 类似background,
//value:blue
//chainable: true,false 设置或者获取。
access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
var i = 0,
length = elems.length,
//key与空进行比较,如果有值,就返回false
bulk = key == null;
// 设定多组值。是json,多组值, 就是设定属性。
if ( jQuery.type( key ) === "object" ) {
chainable = true; //设定
for ( i in key ) {
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
}
// 设定一组值。
} else if ( value !== undefined ) {
chainable = true;
//判断value是否是函数,
if ( !jQuery.isFunction( value ) ) {
raw = true;
}
//如果没有key值,就
if ( bulk ) {
// Bulk operations run against the entire set
if ( raw ) {
fn.call( elems, value );
fn = null;
// ...except when executing function values
} else {
bulk = fn;
fn = function( elem, key, value ) {
return bulk.call( jQuery( elem ), value );
};
}
}
//fn是否存在。
if ( fn ) {
for ( ; i < length; i++ ) {
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
}
}
}
return chainable ?
elems :
// Gets
bulk ?
fn.call( elems ) :
length ? fn( elems[0], key ) : emptyGet;
},
now:获取当前时间。时间戳
now: Date.now, //跟getTime()差不多。
swap: CSS交换。
swap: function( elem, options, callback, args ) {
var ret, name,
old = {};
//保存当前样式
//设定预先设定样式。
for ( name in options ) {
old[ name ] = elem.style[ name ];
elem.style[ name ] = options[ name ];
}
//获取
ret = callback.apply( elem, args || [] );
//还原保存样式
for ( name in options ) {
elem.style[ name ] = old[ name ];
}
return ret;
}
$('div1').css('widht');
$('div1').get(0).offsetWidth;
如果dispaly为none。原生js获取不到了
jQuery就可以获取隐藏元素的值,用的就是swap获取的。
先隐藏到元素显示,然后再隐藏。
用 visibility 和 position:absolubte;