html测试自己的jQuery框架
appendTo
方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- <script src="../jQuery/jquery-3.4.1.min.js"></script> -->
<script src="../jQuery/sjQuery.js"></script>
<script>
$(function () {
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
//1.接收一个字符串 将p添加到指定元素内部的最后
console.log($("p").appendTo(".item"));
//原生js的方法
/*
function appendTo(source, target) { //元素 指定元素
//target.appendChild(source); //将元素添加到指定元素内部的最后
//1.1遍历取出所有指定的元素target
for (var i = 0; i < target.length; i++) {
var targetEle = target[i];
//1.11遍历取出所有的元素source
for (var j = 0; j < source.length; j++) {
var sourceEle = source[j];
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (i == 0) {
//直接添加
targetEle.appendChild(sourceEle);
} else {
//先拷贝再添加
var temp = sourceEle.cloneNode(true);
targetEle.appendChild(temp);
}
}
}
}
var p = document.querySelectorAll("P");
var div = document.querySelectorAll('div');
appendTo(p, div);
console.log(p.cloneNode(true));//<p>我是段落</p>
console.log(p.cloneNode(false));//<p></p>
*/
}
});
</script>
</head>
<body>
<button>测试方法</button>
<p>我是段落</p>
<p>我是段落</p>
<div class="item">
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
</div>
<div class="item">
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
</div>
</body>
</html>
自己的jquery框架,sjQuery.js 316-342行代码
(function (window, undefined) {
var sjQuery = function (selector) {
return new sjQuery.prototype.init(selector);
}
sjQuery.prototype = { //原型
constructor: sjQuery,
init: function (selector) {
//0.去除字符串两边的空格
selector = sjQuery.trim(selector);
//1.传入'' null undefined NaN 0 false,返回空的jQuery对象
if (!selector) {
return this;
} else if (sjQuery.insFuntion(selector)) {
// console.log('是方法');
sjQuery.ready(selector); //把传递进来的回调函数传递给ready方法
}
//2.字符串
else if (sjQuery.isString(selector)) {
//2.1判断是否是代码片段<a>
if (sjQuery.isHTML(selector)) {
//console.log('代码片段');
//1.根据代码片段创建所有的元素
var temp = document.createElement('div');
temp.innerHTML = selector;
// console.log(temp);
//2.将创建好的一级元素添加到jQuery当中
// console.log(temp.children);//children方法
// for (var i = 0; i < temp.children.length; i++) {
// this[i] = temp.children[i];
// }
//3.给jQuery对象添加length属性
//简化第2,3步
[].push.apply(this, temp.children);
//4.返回加工好的this(jQuery)
// return this;
}
//2.2判断是否是选择器
else {
// 1.根据传入的选择器找到对应的元素
var res = document.querySelectorAll(selector);
// 2.将找到的元素添加到sjQuery上
[].push.apply(this, res);
// 3.返回加工上的this
// return this;
}
} //3.数组
// else if(typeof selector==='object'&&'length' in selector&&selector!==window){//window也是对象,并且length=0
/*
//3.1真数组
if(({}).toString.apply(selector)==="[object Array]"){
// console.log('真数组');
//真数组转换为伪数组
[].push.apply(this,selector);
// return this;
}
//3.2伪数组
else{
// console.log('伪数组');
//企业开发中,要将自定义伪数组转换为伪数组,首先将它转换为真数组
//因为IE8及以下不能直接将自定义的伪数组包装成伪数组返回
//将自定义的伪数组转换为真数组
var arr=[].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this,arr);
return this;
}
*/
//简化以上代码
//将自定义的伪数组转换为真数组
else if (sjQuery.isArray(selector)) {
var arr = [].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this, arr);
// return this;
}
//除上述类型以外
else {
this[0] = selector; //将其保存到jQuery
this.length = 1;
// return this;
}
return this;
},
jQuery: "3.4.1", //模拟版本号
selector: "", //默认为空
length: 0,
//[].push找到数组的push方法
//冒号前面的push将由sjQuery对象调用
//相当于[].push.apply(this);,把push内部的this替换成sjQUery对象
push: [].push,
sort: [].sort,
splice: [].splice,
toArray: function () {
return [].slice.call(this);
},
get: function (num) {
//没有传递参数
if (arguments.length === 0) {
return this.toArray();
}
//传递参数,参数不是负数
else if (num >= 0) {
return this[num];
}
//传递负数
else {
return this[this.length + num];
}
},
eq: function (num) {
// 没有传递参数
if (arguments.length === 0) {
return new sjQuery();
} else {
return sjQuery(this.get(num));
}
},
first: function (num) {
return this.eq(0);
},
last: function (num) {
return this.eq(-1);
},
each: function (fn) {
return sjQuery.each(this, fn);
},
map: function (obj, fn) {
}
}
sjQuery.extend = sjQuery.prototype.extend = function (obj) {
for (var key in obj) {
this[key] = obj[key];
}
}
sjQuery.extend({ //key/value
isString: function (str) {
return typeof str === "string"
},
isHTML: function (str) {
return str.charAt(0) == "<" && str.charAt(str.length - 1) == ">" && str.length >= 3
},
trim: function (str) {
//如果不是字符串,则不用去除空格
if (!sjQuery.isString(str)) {
return str;
}
//判断是否支持trim方法
if (str.trim) {
return str.trim();
} else {
return str.replace(/^\s+|\s+$/g, ''); //用空串代替空格字符串
}
},
isObject: function (sele) {
return typeof sele === "object"
},
isWindow: function (sele) {
return sele === window;
},
isArray: function (sele) {
if (sjQuery.isObject(sele) &&
!sjQuery.isWindow(sele) &&
"length" in sele) {
return true;
}
return false;
},
insFuntion: function (sele) {
return typeof sele === 'function';
},
ready: function (fn) { //当传入的是方法函数类型,当判断页面的DOM元素加载完后开始执行代码,比如body里有div,若没有等dom加载完就执行代码,会找不到div
//判断DOM是否加载完毕
if (document.readyState == "complete") {
fn(); //直接回调
} else if (document.addEventListener) { //如果浏览器兼容此方法
document.addEventListener('DOMContentLoaded', function () {
fn();
})
} else {
document.attachEvent('onreadystatechange', function () { //attachEvent不兼容火狐谷歌
if (document.readyState == "complete") {
fn();
}
})
}
},
each: function (obj, fn) {
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
// var res = fn(i, obj[i]);
var res = fn.call(obj[i], i, obj[i]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
// var res = fn(key, obj[key]);
var res = fn.call(obj[key], key, obj[key]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
return obj;
},
map: function (obj, fn) {
var res = [];
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
var temp = fn(obj[i], i);
if (temp) {
res.push(temp);
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
var temp = fn(obj[key], key);
if (temp) {
res.push(temp);
}
}
}
return res;
}
});
sjQuery.prototype.extend({
empty: function () {
//1.遍历所有找到的元素
this.each(function (key, value) {
value.innerHTML = "";
});
//2.方便链式编程
return this;
},
remove: function (sele) {
if (arguments.length == 0) {
//1.遍历指定的元素
this.each(function (key, value) {
//js中,元素不能删除自己,只能通过这个元素找到其父元素,再通过父元素删除它
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
});
} else {
var $this = this;
//1.根据传入的选择器找到对应的元素
$(sele).each(function (Key, value) {
//2.遍历找到的元素,获取对应的类型
var type = value.tagName;
//3.遍历指定的元素
$this.each(function (k, v) {
//4.获取指定元素的类型
var t = v.tagName;
//5.判断找到元素的类型和指定元素的类型
if (t === type) {
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
}
})
})
}
return this;
},
html: function (content) {
if (arguments.length === 0) { //没有传参
return this[0].innerHTML;
} else {
this.each(function (key, value) {
value.innerHTML = content;
})
}
},
text: function (content) {
if (arguments.length === 0) {
var res = "";
//遍历元素,用字符串拼接
this.each(function (key, value) {
res += value.innerText;
});
return res;
} else {
this.each(function (key, value) {
value.innerText = content;
})
}
},
appendTo: function (sele) {
var $target = $(sele);
var $this = this; //$("p").appendTo(".item");p是source元素,也就是this,谁调用谁就是this
var res = [];
//1.1遍历取出所有指定的元素target
$.each($target, function (key, value) {
//1.11遍历取出所有的元素source
$this.each(function (k, v) {
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (key == 0) {
//直接添加
value.appendChild(v);
res.push(v);
} else {
//先拷贝再添加
var temp = v.cloneNode(true);
value.appendChild(temp);
res.push(temp);
}
})
});
//返回所有添加的元素
return $(res);
}
})
sjQuery.prototype.init.prototype = sjQuery.prototype;
window.sjQuery = window.$ = sjQuery;
})(window);
prependTo
方法和appendTo
方法类似
自己的jquery框架,sjQuery.js 343-369行代码
(function (window, undefined) {
var sjQuery = function (selector) {
return new sjQuery.prototype.init(selector);
}
sjQuery.prototype = { //原型
constructor: sjQuery,
init: function (selector) {
//0.去除字符串两边的空格
selector = sjQuery.trim(selector);
//1.传入'' null undefined NaN 0 false,返回空的jQuery对象
if (!selector) {
return this;
} else if (sjQuery.insFuntion(selector)) {
// console.log('是方法');
sjQuery.ready(selector); //把传递进来的回调函数传递给ready方法
}
//2.字符串
else if (sjQuery.isString(selector)) {
//2.1判断是否是代码片段<a>
if (sjQuery.isHTML(selector)) {
//console.log('代码片段');
//1.根据代码片段创建所有的元素
var temp = document.createElement('div');
temp.innerHTML = selector;
// console.log(temp);
//2.将创建好的一级元素添加到jQuery当中
// console.log(temp.children);//children方法
// for (var i = 0; i < temp.children.length; i++) {
// this[i] = temp.children[i];
// }
//3.给jQuery对象添加length属性
//简化第2,3步
[].push.apply(this, temp.children);
//4.返回加工好的this(jQuery)
// return this;
}
//2.2判断是否是选择器
else {
// 1.根据传入的选择器找到对应的元素
var res = document.querySelectorAll(selector);
// 2.将找到的元素添加到sjQuery上
[].push.apply(this, res);
// 3.返回加工上的this
// return this;
}
} //3.数组
// else if(typeof selector==='object'&&'length' in selector&&selector!==window){//window也是对象,并且length=0
/*
//3.1真数组
if(({}).toString.apply(selector)==="[object Array]"){
// console.log('真数组');
//真数组转换为伪数组
[].push.apply(this,selector);
// return this;
}
//3.2伪数组
else{
// console.log('伪数组');
//企业开发中,要将自定义伪数组转换为伪数组,首先将它转换为真数组
//因为IE8及以下不能直接将自定义的伪数组包装成伪数组返回
//将自定义的伪数组转换为真数组
var arr=[].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this,arr);
return this;
}
*/
//简化以上代码
//将自定义的伪数组转换为真数组
else if (sjQuery.isArray(selector)) {
var arr = [].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this, arr);
// return this;
}
//除上述类型以外
else {
this[0] = selector; //将其保存到jQuery
this.length = 1;
// return this;
}
return this;
},
jQuery: "3.4.1", //模拟版本号
selector: "", //默认为空
length: 0,
//[].push找到数组的push方法
//冒号前面的push将由sjQuery对象调用
//相当于[].push.apply(this);,把push内部的this替换成sjQUery对象
push: [].push,
sort: [].sort,
splice: [].splice,
toArray: function () {
return [].slice.call(this);
},
get: function (num) {
//没有传递参数
if (arguments.length === 0) {
return this.toArray();
}
//传递参数,参数不是负数
else if (num >= 0) {
return this[num];
}
//传递负数
else {
return this[this.length + num];
}
},
eq: function (num) {
// 没有传递参数
if (arguments.length === 0) {
return new sjQuery();
} else {
return sjQuery(this.get(num));
}
},
first: function (num) {
return this.eq(0);
},
last: function (num) {
return this.eq(-1);
},
each: function (fn) {
return sjQuery.each(this, fn);
},
map: function (obj, fn) {
}
}
sjQuery.extend = sjQuery.prototype.extend = function (obj) {
for (var key in obj) {
this[key] = obj[key];
}
}
sjQuery.extend({ //key/value
isString: function (str) {
return typeof str === "string"
},
isHTML: function (str) {
return str.charAt(0) == "<" && str.charAt(str.length - 1) == ">" && str.length >= 3
},
trim: function (str) {
//如果不是字符串,则不用去除空格
if (!sjQuery.isString(str)) {
return str;
}
//判断是否支持trim方法
if (str.trim) {
return str.trim();
} else {
return str.replace(/^\s+|\s+$/g, ''); //用空串代替空格字符串
}
},
isObject: function (sele) {
return typeof sele === "object"
},
isWindow: function (sele) {
return sele === window;
},
isArray: function (sele) {
if (sjQuery.isObject(sele) &&
!sjQuery.isWindow(sele) &&
"length" in sele) {
return true;
}
return false;
},
insFuntion: function (sele) {
return typeof sele === 'function';
},
ready: function (fn) { //当传入的是方法函数类型,当判断页面的DOM元素加载完后开始执行代码,比如body里有div,若没有等dom加载完就执行代码,会找不到div
//判断DOM是否加载完毕
if (document.readyState == "complete") {
fn(); //直接回调
} else if (document.addEventListener) { //如果浏览器兼容此方法
document.addEventListener('DOMContentLoaded', function () {
fn();
})
} else {
document.attachEvent('onreadystatechange', function () { //attachEvent不兼容火狐谷歌
if (document.readyState == "complete") {
fn();
}
})
}
},
each: function (obj, fn) {
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
// var res = fn(i, obj[i]);
var res = fn.call(obj[i], i, obj[i]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
// var res = fn(key, obj[key]);
var res = fn.call(obj[key], key, obj[key]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
return obj;
},
map: function (obj, fn) {
var res = [];
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
var temp = fn(obj[i], i);
if (temp) {
res.push(temp);
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
var temp = fn(obj[key], key);
if (temp) {
res.push(temp);
}
}
}
return res;
}
});
sjQuery.prototype.extend({
empty: function () {
//1.遍历所有找到的元素
this.each(function (key, value) {
value.innerHTML = "";
});
//2.方便链式编程
return this;
},
remove: function (sele) {
if (arguments.length == 0) {
//1.遍历指定的元素
this.each(function (key, value) {
//js中,元素不能删除自己,只能通过这个元素找到其父元素,再通过父元素删除它
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
});
} else {
var $this = this;
//1.根据传入的选择器找到对应的元素
$(sele).each(function (Key, value) {
//2.遍历找到的元素,获取对应的类型
var type = value.tagName;
//3.遍历指定的元素
$this.each(function (k, v) {
//4.获取指定元素的类型
var t = v.tagName;
//5.判断找到元素的类型和指定元素的类型
if (t === type) {
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
}
})
})
}
return this;
},
html: function (content) {
if (arguments.length === 0) { //没有传参
return this[0].innerHTML;
} else {
this.each(function (key, value) {
value.innerHTML = content;
})
}
},
text: function (content) {
if (arguments.length === 0) {
var res = "";
//遍历元素,用字符串拼接
this.each(function (key, value) {
res += value.innerText;
});
return res;
} else {
this.each(function (key, value) {
value.innerText = content;
})
}
},
appendTo: function (sele) {
var $target = $(sele);
var $this = this; //$("p").appendTo(".item");p是source元素,也就是this,谁调用谁就是this
var res = [];
//1.1遍历取出所有指定的元素target
$.each($target, function (key, value) {
//1.11遍历取出所有的元素source
$this.each(function (k, v) {
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (key === 0) {
//直接添加
value.appendChild(v);
res.push(v);
} else {
//先拷贝再添加
var temp = v.cloneNode(true);
value.appendChild(temp);
res.push(temp);
}
})
});
//返回所有添加的元素
return $(res);
},
prependTo: function (sele) {
var $target = $(sele);
var $this = this; //$("p").appendTo(".item");p是source元素,也就是this,谁调用谁就是this
var res = [];
//1.1遍历取出所有指定的元素target
$.each($target, function (key, value) {
//1.11遍历取出所有的元素source
$this.each(function (k, v) {
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (key === 0) {
//直接添加
value.insertBefore(v, value.firstChild);
res.push(v);
} else {
//先拷贝再添加
var temp = v.cloneNode(true);
value.insertBefore(temp, value.firstChild);
res.push(temp);
}
})
});
//返回所有添加的元素
return $(res);
}
})
sjQuery.prototype.init.prototype = sjQuery.prototype;
window.sjQuery = window.$ = sjQuery;
})(window);
append
方法和appendTo
方法大同小异
区别在于:
1:写法不同,参数顺序反过来了
2:传入选择器并不会自动创建DOM元素了,比如传入p,会直接将p元素添加在后面,但是传入的是代码片段的话,还是会自动创建DOM元素的
3:返回值类型不同
下面是测试append和prepend的HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- <script src="../jQuery/jquery-3.4.1.min.js"></script> -->
<script src="../jQuery/sjQuery.js"></script>
<script>
$(function () {
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
// $(".item").append("p");
// $(".item").prepend("p");
// $(".item").append("<span>我是span</span>");
//测试有多个p和div的情况
var p = document.querySelectorAll("P");
var div = document.querySelectorAll('div');
// $(div).append(p);
$(div).prepend(p);
}
});
</script>
</head>
<body>
<button>测试方法</button>
<p>我是段落</p>
<p>我是段落</p>
<div class="item">
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
</div>
<div class="item">
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
</div>
</body>
</html>
编写自己的jQuery框架 sjQuery.js 370-387行代码
(function (window, undefined) {
var sjQuery = function (selector) {
return new sjQuery.prototype.init(selector);
}
sjQuery.prototype = { //原型
constructor: sjQuery,
init: function (selector) {
//0.去除字符串两边的空格
selector = sjQuery.trim(selector);
//1.传入'' null undefined NaN 0 false,返回空的jQuery对象
if (!selector) {
return this;
} else if (sjQuery.insFuntion(selector)) {
// console.log('是方法');
sjQuery.ready(selector); //把传递进来的回调函数传递给ready方法
}
//2.字符串
else if (sjQuery.isString(selector)) {
//2.1判断是否是代码片段<a>
if (sjQuery.isHTML(selector)) {
//console.log('代码片段');
//1.根据代码片段创建所有的元素
var temp = document.createElement('div');
temp.innerHTML = selector;
// console.log(temp);
//2.将创建好的一级元素添加到jQuery当中
// console.log(temp.children);//children方法
// for (var i = 0; i < temp.children.length; i++) {
// this[i] = temp.children[i];
// }
//3.给jQuery对象添加length属性
//简化第2,3步
[].push.apply(this, temp.children);
//4.返回加工好的this(jQuery)
// return this;
}
//2.2判断是否是选择器
else {
// 1.根据传入的选择器找到对应的元素
var res = document.querySelectorAll(selector);
// 2.将找到的元素添加到sjQuery上
[].push.apply(this, res);
// 3.返回加工上的this
// return this;
}
} //3.数组
// else if(typeof selector==='object'&&'length' in selector&&selector!==window){//window也是对象,并且length=0
/*
//3.1真数组
if(({}).toString.apply(selector)==="[object Array]"){
// console.log('真数组');
//真数组转换为伪数组
[].push.apply(this,selector);
// return this;
}
//3.2伪数组
else{
// console.log('伪数组');
//企业开发中,要将自定义伪数组转换为伪数组,首先将它转换为真数组
//因为IE8及以下不能直接将自定义的伪数组包装成伪数组返回
//将自定义的伪数组转换为真数组
var arr=[].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this,arr);
return this;
}
*/
//简化以上代码
//将自定义的伪数组转换为真数组
else if (sjQuery.isArray(selector)) {
var arr = [].slice.call(selector);
//将真数组转换为伪数组
[].push.apply(this, arr);
// return this;
}
//除上述类型以外
else {
this[0] = selector; //将其保存到jQuery
this.length = 1;
// return this;
}
return this;
},
jQuery: "3.4.1", //模拟版本号
selector: "", //默认为空
length: 0,
//[].push找到数组的push方法
//冒号前面的push将由sjQuery对象调用
//相当于[].push.apply(this);,把push内部的this替换成sjQUery对象
push: [].push,
sort: [].sort,
splice: [].splice,
toArray: function () {
return [].slice.call(this);
},
get: function (num) {
//没有传递参数
if (arguments.length === 0) {
return this.toArray();
}
//传递参数,参数不是负数
else if (num >= 0) {
return this[num];
}
//传递负数
else {
return this[this.length + num];
}
},
eq: function (num) {
// 没有传递参数
if (arguments.length === 0) {
return new sjQuery();
} else {
return sjQuery(this.get(num));
}
},
first: function (num) {
return this.eq(0);
},
last: function (num) {
return this.eq(-1);
},
each: function (fn) {
return sjQuery.each(this, fn);
},
map: function (obj, fn) {
}
}
sjQuery.extend = sjQuery.prototype.extend = function (obj) {
for (var key in obj) {
this[key] = obj[key];
}
}
sjQuery.extend({ //key/value
isString: function (str) {
return typeof str === "string"
},
isHTML: function (str) {
return str.charAt(0) == "<" && str.charAt(str.length - 1) == ">" && str.length >= 3
},
trim: function (str) {
//如果不是字符串,则不用去除空格
if (!sjQuery.isString(str)) {
return str;
}
//判断是否支持trim方法
if (str.trim) {
return str.trim();
} else {
return str.replace(/^\s+|\s+$/g, ''); //用空串代替空格字符串
}
},
isObject: function (sele) {
return typeof sele === "object"
},
isWindow: function (sele) {
return sele === window;
},
isArray: function (sele) {
if (sjQuery.isObject(sele) &&
!sjQuery.isWindow(sele) &&
"length" in sele) {
return true;
}
return false;
},
insFuntion: function (sele) {
return typeof sele === 'function';
},
ready: function (fn) { //当传入的是方法函数类型,当判断页面的DOM元素加载完后开始执行代码,比如body里有div,若没有等dom加载完就执行代码,会找不到div
//判断DOM是否加载完毕
if (document.readyState == "complete") {
fn(); //直接回调
} else if (document.addEventListener) { //如果浏览器兼容此方法
document.addEventListener('DOMContentLoaded', function () {
fn();
})
} else {
document.attachEvent('onreadystatechange', function () { //attachEvent不兼容火狐谷歌
if (document.readyState == "complete") {
fn();
}
})
}
},
each: function (obj, fn) {
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
// var res = fn(i, obj[i]);
var res = fn.call(obj[i], i, obj[i]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
// var res = fn(key, obj[key]);
var res = fn.call(obj[key], key, obj[key]);
if (res === true) {
continue;
} else if (res === false) {
break;
}
}
}
return obj;
},
map: function (obj, fn) {
var res = [];
// 1.判断是否是数组
if (sjQuery.isArray(obj)) {
for (var i = 0; i < obj.length; i++) {
var temp = fn(obj[i], i);
if (temp) {
res.push(temp);
}
}
}
// 2.判断是否是对象
else if (sjQuery.isObject(obj)) {
for (var key in obj) {
var temp = fn(obj[key], key);
if (temp) {
res.push(temp);
}
}
}
return res;
}
});
sjQuery.prototype.extend({
empty: function () {
//1.遍历所有找到的元素
this.each(function (key, value) {
value.innerHTML = "";
});
//2.方便链式编程
return this;
},
remove: function (sele) {
if (arguments.length == 0) {
//1.遍历指定的元素
this.each(function (key, value) {
//js中,元素不能删除自己,只能通过这个元素找到其父元素,再通过父元素删除它
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
});
} else {
var $this = this;
//1.根据传入的选择器找到对应的元素
$(sele).each(function (Key, value) {
//2.遍历找到的元素,获取对应的类型
var type = value.tagName;
//3.遍历指定的元素
$this.each(function (k, v) {
//4.获取指定元素的类型
var t = v.tagName;
//5.判断找到元素的类型和指定元素的类型
if (t === type) {
//根据遍历到的元素找到对象的父元素
var parent = value.parentNode;
//通过父元素删除指定的元素
parent.removeChild(value);
}
})
})
}
return this;
},
html: function (content) {
if (arguments.length === 0) { //没有传参
return this[0].innerHTML;
} else {
this.each(function (key, value) {
value.innerHTML = content;
})
}
},
text: function (content) {
if (arguments.length === 0) {
var res = "";
//遍历元素,用字符串拼接
this.each(function (key, value) {
res += value.innerText;
});
return res;
} else {
this.each(function (key, value) {
value.innerText = content;
})
}
},
appendTo: function (sele) {
var $target = $(sele);
var $this = this; //$("p").appendTo(".item");p是source元素,也就是this,谁调用谁就是this
var res = [];
//1.1遍历取出所有指定的元素target
$.each($target, function (key, value) {
//1.11遍历取出所有的元素source
$this.each(function (k, v) {
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (key === 0) {
//直接添加
value.appendChild(v);
res.push(v);
} else {
//先拷贝再添加
var temp = v.cloneNode(true);
value.appendChild(temp);
res.push(temp);
}
})
});
//返回所有添加的元素
return $(res);
},
prependTo: function (sele) {
var $target = $(sele);
var $this = this; //$("p").appendTo(".item");p是source元素,也就是this,谁调用谁就是this
var res = [];
//1.1遍历取出所有指定的元素target
$.each($target, function (key, value) {
//1.11遍历取出所有的元素source
$this.each(function (k, v) {
//1.2判断当前是否是第0个指定的元素 因为本来放在了第一个div后面的p,在遍历到第二个div时,将第一个div的p放到了第二个div后面,所以需要克隆p
if (key === 0) {
//直接添加
value.insertBefore(v, value.firstChild);
res.push(v);
} else {
//先拷贝再添加
var temp = v.cloneNode(true);
value.insertBefore(temp, value.firstChild);
res.push(temp);
}
})
});
//返回所有添加的元素
return $(res);
},
append: function (sele) {
//判断传入的参数是否是字符串
if (sjQuery.isString(sele)) { //如果是字符串,直接添加
this[0].innerHTML += sele;//jQuery对象没有innerHTML,只有原生的DOM元素中才有,要从对象上取出DOM元素,就是this[0]
}else{
$(sele).appendTo(this);//顺序和appendTo相反,其他功能都是一样的
}
return this;
},
prepend:function(sele){
//判断传入的参数是否是字符串
if (sjQuery.isString(sele)) { //如果是字符串,直接添加
this[0].innerHTML = sele+this[0].innerHTML;//jQuery对象没有innerHTML,只有原生的DOM元素中才有,要从对象上取出DOM元素,就是this[0]
}else{
$(sele).prependTo(this);//顺序和appendTo相反,其他功能都是一样的
}
return this;
}
})
sjQuery.prototype.init.prototype = sjQuery.prototype;
window.sjQuery = window.$ = sjQuery;
})(window);