jQuery抽象方法追踪(0)
w3school最简单的jQuery使用方法如下
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
});
});
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
</body>
</html>
如果使用原生js,如下
<html>
<head>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', domReadyHandler);
function domReadyHandler() {
var nodes = document.getElementsByTagName("p");
for(var i=0; i<nodes.length; i++) {
nodes[i].onclick = function() {
this.style.display = "none";
};
}
}
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
</body>
</html>
抽象分为数据抽象、过程抽象,网页最基本的处理对象便是DOM对象,jQuery使用了$作为入口函数,传入选择标示,如document
,"p"
,this
,返回基于DOM对象构造后的对象,结构如下:
function $(selector) {
return new makeQ(selector);
function makeQ(selector) {...}
}
因为document,this
直接就是DOM对象,"p"
是字符串,所以要分情况构造(工厂模式):
function $(selector) {
return new makeQ(selector);
function makeQ(selector) {
if(typeof selector === "string") {
//...
} else {
//...
}
}
}
然后将DOM对象找到绑定到构造后的对象上
function $(selector) {
return new makeQ(selector);
function makeQ(selector) {
if(typeof selector === "string") {
var nodes = document.getElementsByTagName(selector);
for(var i=0; i< nodes.length; i++) {
this[i] = nodes[i];
}
} else {
this[0] = selector;
}
}
}
然后绑定相应的处理函数
function $(selector) {
return new makeQ(selector);
function makeQ(selector) {
if(typeof selector === "string") {
var nodes = document.getElementsByTagName(selector);
for(var i=0; i< nodes.length; i++) {
this[i] = nodes[i];
}
this.click = function(callback) {
for(var i in this) {
this[i].onclick = callback;
}
}
} else {
this[0] = selector;
this.ready = function(callback) {
this[0].addEventListener('DOMContentLoaded', callback);
}
this.hide = function() {
this[0].style.display = "none";
}
}
}
}
最终代码如下:
<html>
<head>
<script type="text/javascript">
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
});
});
function $(selector) {
return new makeQ(selector);
function makeQ(selector) {
if(typeof selector === "string") {
var nodes = document.getElementsByTagName(selector);
for(var i=0; i< nodes.length; i++) {
this[i] = nodes[i];
}
this.click = function(callback) {
for(var i in this) {
this[i].onclick = callback;
}
}
} else {
this[0] = selector;
this.ready = function(callback) {
this[0].addEventListener('DOMContentLoaded', callback);
}
this.hide = function() {
this[0].style.display = "none";
}
}
}
}
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
</body>
</html>
update:2015-2-19
因为makeQ
构造是同类对象,所以方法应该绑定在原型对象上,同时内存中也减少了重复的方法,修改后的代码如下:
<html>
<head>
<script type="text/javascript">
$(document).ready(function(){
$("p").click(function(){
$(this).hide();
});
});
function $(selector) {
function makeQ(selector) {
if(typeof selector === "string") {
var nodes = document.getElementsByTagName(selector);
for(var i=0; i< nodes.length; i++) {
this[i] = nodes[i];
}
} else if(selector === document){
this[0] = selector;
this.ready = function(callback) {
this[0].addEventListener('DOMContentLoaded', callback);
}
} else {
this[0] = selector;
}
}
makeQ.prototype = {
click:function(callback) {
for(var i in this) {
if(!isNaN(i)) {
this[i].onclick = callback;
}
}
},
hide:function() {
for(var i in this) {
if(!isNaN(i)) {
this[i].style.display = "none";
}
}
}
}
return new makeQ(selector);
}
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
</body>
</html>