48jQuery相关

JQuery源码难点包含:1、模块处理,2、无new构建,3、深克隆
一、jQuery零碎知识
1、把jQuery对象转化为js对象(1)$div[0];(2)$div.get(0);
2、仍然获取jQuery对象(1)$div.eq(0);
3、把js对象转化为jQuery对象$(div)
6、find()沿着 DOM 树向下遍历所有层级
7、children()沿着 DOM 树向下遍历单一层级。
8、对于HTML元素本身就带有的固有属性,在处理时,使用prop方法。
9、对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法
10、具有 true 和 false 两个属性的属性,如 checked, selected 或者 disabled 使用prop()
11、$(this).attr("checked",!this.checked);(1)$(this)有attr方法(2)this有checked属性

二、jQuery类库源码总解读
```javascript
( function( global, factory ) {
"use strict";
if ( typeof module === "object" && typeof module.exports === "object" ) {

module.exports = global.document ?
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};
} else {
factory( global );
}
} )( typeof window !== "undefined" ? window : this/*第1个实参:判断运行环境中,是否有window对象,有则为window,没有为this*/, function( window, noGlobal ) {} /*第2个实参*/);
```
在Node环境下,通过npm install jquery和var AAA = require("jquery")(window),引进jQuery类库,通过AAA.调用。这段代码为处理下列情形准备的:
1、运行环境有window对象,传入(window,factory)
(1)有module对象和module.exports对象,
A、有window.document对象,执行module.exports =factory( window, true )
B、没window.document对象,执行module.exports =function( w ) {}
(2)没module对象和module.exports对象,执行factory( window ),这是前端程序员常使用的情形
2、运行环境没window对象,传入(this,factory)
(1)有module对象和module.exports对象,
A、有this.document对象,执行module.exports =factory( this, true )
B、没this.document对象,执行module.exports =function( w ) {}
(2)没module对象和module.exports对象,执行factory( this )

三、jQuery实例的无new构建(3段)
```javascript
var AQuery = function(selector, context) {
return new AQuery.prototype.init();
};
AQuery.prototype = {
init: function() {
this.attributeA = "attribute1";
return this;/*???:init后来被new了,所以这里不需要return this*/
},
methodA: function() {
this.attributeB = "attribute2";
return this;/*为了链式调用,所以这里需要return this*/
},
attributeC: "attribute3"
};
AQuery.prototype.init.prototype = AQuery.prototype
```
思路:
(1)jQuery执行时,new它原型上的init方法;
(2)把init方法的原型指向jQuery的原型
(4)来源:https://segmentfault.com/a/1190000003501504

四、extend方法源码
```javascript
//jQuery.extend({myFunction:function(){}});
//jQuery.extend(true,{myFunction:function(){}})
//jQuery.extend({myObject:[1,2,3,4,5,{a:1,b:[6,7,8,9,0]}]});
//jQuery.extend(true,{myObject:[1,2,3,4,5,{a:1,b:[6,7,8,9,0]}]});
jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
if ( length === i ) {
target = this;
--i;
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
// 假如出现如下情形
// target={ name:a};
// copy = a;
if ( target === copy ) {//当被扩展的对象和拷贝的内容一样时直接跳过这次循环,如$.extend( true , { name : 5}, { name : { name : 5}});
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
/*$.fn.extend(true,{a:{b:{c:1}}});*/
console.log(src);//undefined
clone = src && jQuery.isPlainObject(src) ? src : {};
console.log(clone);//{b:{c:1}}
/*疑问:要么clone=undefined;要么clone={}。为什么是clone={b:{c:1}}呢?
解释:最后1次递归没有运行这行代码,src和clone的值是在别处分别赋值的*/
}
// Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy );/*
$.fn.extend(true,{a:{b:{c:1}}});的执行过程
第1次克隆
this[ a ] = jQuery.extend( deep, {}, {b:{c:1}} );即
this.a = jQuery.extend( deep, {}, {b:{c:1}} );
第2次克隆
{}[ b ] = jQuery.extend( deep, {}, {c:1} );即
{b:jQuery.extend( deep, {}, {c:1} )};这个对象赋值给了this.a */
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
/*
第3次克隆
{}[ c ] = 1;即
{c:1};这个对象作为b的属性值
*/
}
}
}
}
// Return the modified object
return target;
};
```
五、extend方法应用
注意:被克隆的只能是键值对,值可以是任何数据类型,第一个参数如果为true,则是深克隆,当值是键值对或数组时发挥作用。
```javascript
jQuery.extend(true,{
key1: value1,
key2: value2
})
```
实例:供查看执行步骤
```html:run
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>
</head>
<body>
</body>
</html>
<script>
debugger;
console.log("================");
$.fn.extend(true,{a:{b:{c:1}}});
</script>
```

六、each方法源码
```javascript
jQuery.fn = jQuery.prototype = {
each: function( callback, args ) {
return jQuery.each( this, callback, args );
}
};

jQuery.extend({
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 ( ; i < length; i++ ) {
value = callback.call( obj[ i ], i, obj[ i ] );

if ( value === false ) {
break;
}
}
} else {
for ( i in obj ) {
value = callback.call( obj[ i ], i, obj[ i ] );

if ( value === false ) {
break;
}
}
}
}

return obj;
}
});
```

七、jQuery版文件上传
```html:run
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery版文件上传</title>
<script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script>
<style type="text/css">
*{margin:0;padding:0;}
.fileSubmit{background:lightgray;height:900px;padding-top:1px;}
.fileSubmit .detail{margin:70px 0 0 100px;}
.fileSubmit .detail .item{font-size: 17px;height:40px;line-height: 40px;}
.fileSubmit .detail .item span{display:inline-block;font-size: 17px;}
.fileSubmit .detail .item button{display:inline-block;font-size: 17px;margin-left: 50px;width:60px;height:25px;border-radius: 5px;}
.fileSubmit .detail .item input{font-size: 15px;margin-left: 50px;width:210px;height:25px;}
</style>
</head>
<body>
<div class="fileSubmit">
<ul class="detail">
<li class="item">名称:<span id="name">工业监测审计系统</span></li>
<li class="item">型号:<span id="type">INA-200</span></li>
<li class="item">硬件版本:<span id="hardwareVersion">INA-200-V1802005C</span></li>
<li class="item">软件版本:<span id="softwareVersion">V2.0</span><button id="upgradeButton">升级</button><input type="file" id="upgradeInput"/></li>
<li class="item">序列号:<span id="serialNumber">CY18-NA2B-A018-5081</span></li>
<li class="item">制造商:<span id="manufacturer"> 钱老六(北京)有限公司</span></li>
<li class="item">出厂日期:<span id="productionDate">2018年2月10日</span></li>
</ul>
</div>
</body>
</html>
<script type="text/javascript">
$("#upgradeInput").change(function(){
console.log($("#upgradeInput").val());
});
$(function () {
$("#upgradeButton").click(function () {
var upgradeInput = $("#upgradeInput").val();
console.log(typeof (upgradeInput));
if (upgradeInput === "" || upgradeInput.size <= 0) {
alert("请上传文件");
return;
}
var formFile = new FormData();
formFile.append("action", "UploadVMKImagePath");
formFile.append("file", upgradeInput);

$.ajax({
url: "/Admin/Ajax/VMKHandler.ashx",
data: formFile,
type: "Post",
dataType: "json",
cache: false,
processData: false,
contentType: false,
success: function (result) {
alert("上传完成!");
}
})
})
})
</script>
```
参考:https://www.cnblogs.com/LoveTX/p/7081515.html

八、各种高
1、height(仅内容)
2、innerHeight(包括补白)
3、outerHeight(包括补白和边框)
4、outerHeight(true,包括补白、边框、margin)








猜你喜欢

转载自www.cnblogs.com/gushixianqiancheng/p/10966943.html
48