$ 選擇器的實現
<!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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
</style>
</head>
<body>
<a>鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
// 類中的this 指向我們的實例化對象
class 央央{
constructor(arg){
// 判斷參數類型
if(typeof arg === "string"){ //如果是一個字符串類型,就先獲取元素然後通過 setElement 把元素都綁定在 this 上
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){ //如果是一個對象類型,就通過 setElement 把元素都綁定在 this 上
this.setElement(arg);
} else if(typeof arg === "function"){//如果傳入的是一個 function 就在文檔讀完之後執行這個函數
// DOMContentLoaded 文檔讀完
// onload 資源也都加載完
window.addEventListener("DOMContentLoaded",arg);
}
}
setElement(eles){
if(eles.length === undefined){ // 當 eles 只是一個元素的時候
this[0] = eles;
this.length = 1;
// 把這個元素加 this 上,並被給 this 加length 變成一組元素,方便後續的邏輯處理
} else {
// 如果 eles 一組元素,就把每一個都加在 this 上
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
// 給this加 length,方便後邊循環
}
}
click(fn){ // 給 JQ 對象上所有元素添加一個點擊的處理
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
}
}
function $(...arg){
return new 央央(...arg);
}
let btns = document.querySelector("button");
$(btns[0]).click(function(){
console.log(this);
});
</script>
</body>
</html>
JQ的鏈式操作
<!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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
</style>
</head>
<body>
<a>鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
class 央央{
constructor(arg){
if(typeof arg === "string"){
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){
this.setElement(arg);
} else if(typeof arg === "function"){
window.addEventListener("DOMContentLoaded",arg);
}
}
eq(index){
return $(this[index]);
}
setElement(eles){
if(eles.length === undefined){
this[0] = eles;
this.length = 1;
} else {
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
}
}
click(fn){
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
// 類的原型中的方法, this 指向 實例化對象
return this; // 把這個實例化對象接着返回
}
}
function $(...arg){
return new 央央(...arg);
}
//console.log($("button").eq(1));
// $("button").click(function(){
// console.log(12);
// }).eq(0).click(function(){
// console.log("這是0");
// });
console.log($("button").eq(0));
</script>
</body>
</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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
</style>
</head>
<body>
<a>鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
// root 在操作當前次的時候,傳入上一次的操作對象
class 央央{
constructor(arg,root){
root = root||$(document,{});
this["prevObject"] = root;// 把上一次的操作對象存入 this 的 prevObject 屬性
if(typeof arg === "string"){
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){
this.setElement(arg);
} else if(typeof arg === "function"){
window.addEventListener("DOMContentLoaded",arg);
}
}
// 調用 end 方法,返回我們上一次的操作對象
end(){
return this["prevObject"];
}
eq(index){
// 注意當用戶調用 eq 方法之後,這會 操作對象會進行改變,返回把上一次的this 傳入
return $(this[index],this);
}
setElement(eles){
if(eles.length === undefined){
this[0] = eles;
this.length = 1;
} else {
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
}
}
click(fn){
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
return this;
}
}
function $(...arg){
return new 央央(...arg);
}
console.log($("button").eq(0).end());
</script>
</body>
</html>
on 事件綁定
<!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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
</style>
</head>
<body>
<a>鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
// root 在操作當前次的時候,傳入上一次的操作對象
class 央央{
constructor(arg,root){
root = root||$(document,{});
this["prevObject"] = root;// 把上一次的操作對象存入 this 的 prevObject 屬性
if(typeof arg === "string"){
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){
this.setElement(arg);
} else if(typeof arg === "function"){
window.addEventListener("DOMContentLoaded",arg);
}
}
// 調用 end 方法,返回我們上一次的操作對象
end(){
return this["prevObject"];
}
eq(index){
// 注意當用戶調用 eq 方法之後,這會 操作對象會進行改變,返回把上一次的this 傳入
return $(this[index],this);
}
setElement(eles){
if(eles.length === undefined){
this[0] = eles;
this.length = 1;
} else {
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
}
}
click(fn){
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
return this;
}
// 添加事件
on(eventNames,fn){
// eventNames eventNames 中可以存放多個 事件名稱,每個事件名稱中間用 空格 隔開
eventNames = eventNames.trim().split(" ");
eventNames = eventNames.filter(item=>item); // "" --> false 非空字符 true
for(let i = 0; i < this.length; i++){
for(let j = 0; j < eventNames.length; j++){
this[i].addEventListener(eventNames[j],fn);
}
}
}
}
function $(...arg){
return new 央央(...arg);
}
$("button").on(" click mouseout ",function(){
console.log("11");
});
</script>
</body>
</html>
css() 方法實現
<!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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
button {
width: 55px;
}
</style>
</head>
<body>
<a id="a">鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
// root 在操作當前次的時候,傳入上一次的操作對象
class 央央{
constructor(arg,root){
root = root||$(document,{});
this["prevObject"] = root;// 把上一次的操作對象存入 this 的 prevObject 屬性
if(typeof arg === "string"){
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){
this.setElement(arg);
} else if(typeof arg === "function"){
window.addEventListener("DOMContentLoaded",arg);
}
}
// 調用 end 方法,返回我們上一次的操作對象
end(){
return this["prevObject"];
}
eq(index){
// 注意當用戶調用 eq 方法之後,這會 操作對象會進行改變,返回把上一次的this 傳入
return $(this[index],this);
}
setElement(eles){
if(eles.length === undefined){
this[0] = eles;
this.length = 1;
} else {
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
}
}
click(fn){
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
return this;
}
// 添加事件
on(eventNames,fn){
eventNames = eventNames.trim().split(" ");
eventNames = eventNames.filter(item=>item);
for(let i = 0; i < this.length; i++){
for(let j = 0; j < eventNames.length; j++){
this[i].addEventListener(eventNames[j],fn);
}
}
}
// css 方法
css(...arg){
if(typeof arg[0] === "string"){
if(arg.length > 1){
// 兩個參數 設置樣式
for(let i = 0; i < this.length; i++){
央央.setStyle(this[i],arg[0],arg[1]);
}
} else {
// 一個參數獲取樣式
return 央央.getStyle(this[0],arg[0]);
}
} else if(typeof arg[0] === "object"){
// 批量設置樣式
//console.log(arg[0]);
for(let i = 0; i < this.length; i++){
for(let s in arg[0]){
//console.log(s,arg[0][s]);
央央.setStyle(this[i],s,arg[0][s]);
}
}
}
return this;//鏈式樣式
}
static setStyle(el,attr,val){
if(attr in $.cssHooks){ // 如果 attr 這條是樣式,用戶設置 hooks,直接調用hooks把設置權交還給用戶
$.cssHooks[attr].set(el,val);
} else {
el.style[attr] = val;
}
}
static getStyle(el,attr){
return getComputedStyle(el)[attr];
}
}
function $(...arg){
return new 央央(...arg);
}
$.cssHooks = {
width:{
set(el,val){ // 設置 width 時 會觸發的方法
//console.log(el,val);
//console.log("準備開始設置width",val);
el.style.transition = ".2s";
el.style.width = val;
setTimeout(()=>{
el.style.transition = "none";
},100);
//console.log("已經設置了width",val);
},
get(){// 獲取樣式時會觸發的方法
return "獲取時的值";
}
}
};
//$("button").css("width","100px");
//央央.setStyle(a,"color","red");
//console.log($("button").css("width"));
$("button").click(function(){
// $(this).css("height","200px");
});
</script>
</body>
</html>
csshooks 方法的實現
<!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="js/Jquery.js"></script>
<style>
.active {
background: red;
}
button {
width: 55px;
}
</style>
</head>
<body>
<a id="a">鏈接</a>
<button class="active">按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<script>
// root 在操作當前次的時候,傳入上一次的操作對象
class 央央{
constructor(arg,root){
root = root||$(document,{});
this["prevObject"] = root;// 把上一次的操作對象存入 this 的 prevObject 屬性
if(typeof arg === "string"){
let ele = document.querySelectorAll(arg);
this.setElement(ele);
} else if(typeof arg === "object"){
this.setElement(arg);
} else if(typeof arg === "function"){
window.addEventListener("DOMContentLoaded",arg);
}
}
// 調用 end 方法,返回我們上一次的操作對象
end(){
return this["prevObject"];
}
eq(index){
// 注意當用戶調用 eq 方法之後,這會 操作對象會進行改變,返回把上一次的this 傳入
return $(this[index],this);
}
setElement(eles){
if(eles.length === undefined){
this[0] = eles;
this.length = 1;
} else {
for(let i = 0; i < eles.length;i++){
this[i] = eles[i];
}
this.length = eles.length;
}
}
click(fn){
for(let i = 0; i < this.length; i++){
this[i].addEventListener("click",fn);
}
return this;
}
// 添加事件
on(eventNames,fn){
eventNames = eventNames.trim().split(" ");
eventNames = eventNames.filter(item=>item);
for(let i = 0; i < this.length; i++){
for(let j = 0; j < eventNames.length; j++){
this[i].addEventListener(eventNames[j],fn);
}
}
}
// css 方法
css(...arg){
if(typeof arg[0] === "string"){
if(arg.length > 1){
// 兩個參數 設置樣式
for(let i = 0; i < this.length; i++){
央央.setStyle(this[i],arg[0],arg[1]);
}
} else {
// 一個參數獲取樣式
return 央央.getStyle(this[0],arg[0]);
}
} else if(typeof arg[0] === "object"){
// 批量設置樣式
//console.log(arg[0]);
for(let i = 0; i < this.length; i++){
for(let s in arg[0]){
//console.log(s,arg[0][s]);
央央.setStyle(this[i],s,arg[0][s]);
}
}
}
return this;//鏈式樣式
}
static setStyle(el,attr,val){
if(attr in $.cssHooks){ // 如果 attr 這條是樣式,用戶設置 hooks,直接調用hooks把設置權交還給用戶
$.cssHooks[attr].set(el,val);
} else {
el.style[attr] = val;
}
}
static getStyle(el,attr){
if(attr in $.cssHooks){
return $.cssHooks[attr].get(el);
}
return getComputedStyle(el)[attr];
}
}
function $(...arg){
return new 央央(...arg);
}
$.cssHooks = {
width:{
set(el,val){
el.style.width = val;
},
get(el){// 獲取樣式時會觸發的方法
return "就不告訴你";
}
}
};
//$("button").css("width","100px");
//央央.setStyle(a,"color","red");
//console.log($("button").css("width"));
$("button").click(function(){
// $(this).css("height","200px");
console.log($(this).css("width"));
});
</script>
</body>
</html>