Paste_Image.png
在上一篇 零基础打造自己的 js 类库(1) 中,原本只是为了写个小案例,说明一下闭包,js对象的作用。
后来我隐约有一个想法,我是不是可以将miniQuery写得更完善一些呢。我的意思是说,尽量使用jQuery的调用规则,看看自己能不能把常用的方法模拟出来?
这个想法产生以后,我感觉挺兴奋,正好可以藉由这个机会把js的知识点再复习一下。
今后只要有时间,我就把miniQuery更新一下,添加新的api方法进去。作为自己的一个学习记录。
零基础打造自己的 js 类库(1) 写完后,我又陆陆续续地改了很多代码,继而有了下面这个版本,暂且就叫做miniQuery v2.0吧,嘿嘿。
Paste_Image.png
Paste_Image.png
API方法目前大概分为 三个区域:
1. dom 相关 : 主要获取dom元素
2. css 相关:给dom元素设置css样式
3. 事件相关 :给元素添加事件
4. 属性相关:对元素属性进行各种操作
5. 简易ui : 额,目前只写了一个按钮
我利用零碎时间写了一个礼拜,没想到假模假式的也弄了不少方法了,当然,这些肯定是远远不够的。不够以后写案例的时候我差不多就可以直接调用这个miniQuery.js了,主要方便了自己,如果觉得有必要,我就可以立即在里面添加新的方法,实现了订制功能。
当然,目前这个版本功能还比较少,bug估计还有很多,不过没关系,反正就搞着玩玩,出了问题自己背锅就行了。主要还是用于培养兴趣,我本身不是做前端开发的,但是个人隐约感觉js在未来必定会火,当然现在也非常受欢迎了,我打算继续学下去。
首先来看看miniQuery怎么使用吧。
来一个测试页面,引入miniQuery
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="js/miniQuery.js"></script>
<title>测试页面</title>
<script type="text/javascript">
window.onload = function(){
}
</script>
</head>
<body>
<div class='box'></div>
</body>
</html>
页面上只画了一个div,其他啥也没有。
Paste_Image.png
div没有宽高。
接下来,我们用miniQuery来拿到这个对象。
var $box = $('.box').eq(0);
console.log($box);
Paste_Image.png
可见,返回的并不是一个dom对象,而是一个miniQuery对象,具体的原理在上一节中已经阐明。
OK,我们来给它定义宽高和背景色。
var $box = $('.box').eq(0);
$box.css({
width : 80 ,
height : 80 ,
background : 'deeppink'
});
效果:
Paste_Image.png
我们在api上还看到有width,height,backgroundColor方法,而且miniQuery还支持链式调用,所以能这么写:
$box.height(80).width(80).backgroundColor('deeppink');
效果是一样的。
然后,我们给它添加一个事件,当点击的时候就把颜色换为skyblue:
var $box = $('.box').eq(0);
$box.css({
width : 80 ,
height : 80 ,
background : 'deeppink'
}).on('click',function(){
this.css({
background:'skyblue'
});
});
123.gif
再来看一看简单的ui。
我们来引入css文件:
<link rel="stylesheet" type="text/css" href="css/mui.css"/>
var $box = $('.box').eq(0);
$box.linkbutton();
Paste_Image.png
按钮的样式就出来了,然后我们来设置按钮的属性。
var $box = $('.box').eq(0);
$box.linkbutton({
text : '保存' ,
click : function(){
alert('保存成功!');
}
});
Paste_Image.png
按钮的大小也自动变大了。
123.gif
至于其他方法,我就不一一测试了,问题肯定还是有的,以后慢慢完善吧。
至于这个miniQuery的具体实现,以后有机会的话我再开贴记录吧。
附上目前的源代码:
mui.css
.linkbutton {
padding: .4em .9em; /*em的好处就是随着父元素的字体大小而变化,当该元素的字体变化时,会自适应*/
border: 1px solid rgba(0,0,0,.1);
background-color: #ac0;
border-radius: .2em;
box-shadow: 0 1px 5px rgba(0,0,0,.5);
color: #fff;
text-shadow: 0 -.06em .24em rgba(0,0,0,.5); /*将阴影设置为半透明,就无所谓底色了,都能很好地适应*/
font-size: 130%;
line-height: 1.5; /*行高是字号的1.5倍*/
display:inline-block;
cursor:pointer;
font-family: "微软雅黑";
}
"use strict";
/**
* miniQuery 和 工具类库
* 版本 2.0 (修正了一部分Bug,增加了一些方法)
* 作者:剽悍一小兔
*/
// ------------------------ 基本扩展, 字符串,数组等---------------------------------//
function extend_base (){
if(!String.prototype.format ){
String.prototype.format = function() {
var e = arguments;
return this.replace(/{(\d+)}/g,function(t, n) {
return typeof e[n] != "undefined" ? e[n] : t
})
};
}
if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") {
Array.prototype.forEach = function(callback, context) {
// 遍历数组,在每一项上调用回调函数,这里使用原生方法验证数组。
if (Object.prototype.toString.call(this) === "[object Array]") {
var i,len;
//遍历该数组所有的元素
for (i = 0, len = this.length; i < len; i++) {
if (typeof callback === "function" && Object.prototype.hasOwnProperty.call(this, i)) {
if (callback.call(context, this[i], i, this) === false) {
break; // or return;
}
}
}
}
};
}
if(!String.prototype.format ){
Array.isArray = function(obj){
return obj.constructor.toString().indexOf('Array') != -1;
}
}
}
extend_base();
// ------------------------ 工具包---------------------------------//
var utils = {
center : function(dom){
dom.style.position = 'absolute';
dom.style.top = '50%';
dom.style.left = '50%';
dom.style['margin-top'] = - dom.offsetHeight / 2 + 'px';
dom.style['margin-left'] = - dom.offsetWidth / 2 + 'px';
},
/** dom相关 * */
isDom : ( typeof HTMLElement === 'object' ) ?
function(obj){
return obj instanceof HTMLElement;
} :
function(obj){
return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
} ,
/** 数组相关 * */
isArray : function(obj){
return obj.constructor.toString().indexOf('Array') != -1;
}
}
// ------------------------ miniQuery.js ---------------------------------//
;(function(win){
var miniQuery = function(selector){
var miniQuery = null;
var length = 0;
var children = [];
if(!selector) return;
/** 1. 传入的是id * */
if(selector.toString().indexOf('#') != -1) {
selector = selector.replace('#','');
miniQuery = document.getElementById(selector);
}
/** 2. 传入的是class * */
else if(selector.toString().indexOf('.') != -1){
selector = selector.replace('.','');
miniQuery = document.getElementsByClassName(selector);
}
/** 3. 传入的是dom元素 * */
else if(utils.isDom(selector)){
miniQuery = selector;
}
if(!miniQuery) return; //如果本类库包装不了,就返回
if(miniQuery.length){ //如果是一个类数组元素的话,就获取他的长度
length = miniQuery.length;
}else{
length = 1; //这种情况,说明成功包裹了元素,但是该元素还是存在的,就将长度设定为1
}
children = miniQuery.children; //取得所有的孩子节点
return {
/** 属性区 */
obj : miniQuery, //返回的dom元素
index : 0 , //默认的角标(假如 miniquery 是一个类数组的话)
length : length, //元素的个数(假如 miniquery 是一个类数组的话)
children : children,//所有孩子节点
/** 方法区 */
// ------------------------ dom 相关 ---------------------------------//
/**获取dom对象本身,返回纯粹的dom元素,而非miniQuery元素*/
getObj : function(){
return this.obj;
} ,
/**获取元素的长度*/
size : function(){
return this.length;
} ,
/** 假如 miniquery 是一个类数组的话,用于返回其中一个元素 */
eq : function(index){
if(length > 0) {
return $(this.obj[index]); //eq返回的还是miniQuery对象
}else{
return null;
}
} ,
/** 获得第一个匹配元素 */
first : function(){
return $(this.obj[0]);
} ,
/** 获得最后一个匹配元素 */
last : function(){
return $(this.obj[this.length - 1]);
} ,
/** 获得最后一个匹配元素 */
getChildren : function(){
return this.obj.children;
} ,
/** 获得某一个孩子节点 */
getChild : function(i){
return $(this.children[i]);
} ,
/** 获得父节点 */
getParent : function(){
return $(this.obj.parentElement);
} ,
/** 获得上一个节点 */
previous : function(){
var parent = this.getParent();
var children = parent.children;
for(var i = 0; i < children.length; i++){
if(this.obj == children[i]) {
return $(children[i - 1]);
}
}
return null;
} ,
/** 获得下一个节点 */
next : function(){
var parent = this.getParent();
var children = parent.children;
for(var i = 0; i < children.length; i++){
if(this.obj == children[i]) {
return $(children[i + 1]);
}
}
return null;
} ,
findClassDom : function(className){
this.obj = this.obj.getElementsByClassName(className) ;
return this ;
} ,
findIdDom : function(id){
var $this = this;
var children = this.getChildren();
children = Array.prototype.slice.call(children); //obj 转 []
children.forEach(function(item){
//console.log(item.id);
(id === item.id) && ($this = item) ;
});
return this ;
} ,
// ------------------------ css 相关 ---------------------------------//
/** 添加背景色 */
backgroundColor : function(color){
this.obj.style.backgroundColor = color;
return this;
} ,
/** 获取style */
getStyle : function(){
var styleEle = null;
if(window.getComputedStyle){
styleEle = window.getComputedStyle(this.obj,null);
}else{
styleEle = ht.currentStyle;
}
return styleEle;
} ,
/** 设置或者拿到高度 */
height : function(h){
if(!h) return this.getStyle().getPropertyValue('height');
(typeof h == 'number') && (h = h + 'px');
this.obj.style.height = h;
return this;
} ,
/** 设置或者拿到宽度 */
width : function(w){
if(!w) return this.getStyle().getPropertyValue('width');
(typeof w == 'number') && (w = w + 'px');
this.obj.style.width = w;
return this;
} ,
/** 设置自定义样式 */
css : function(obj){
if(!obj) return;
for(var key in obj){
//console.log(key + '=========' + obj[key]);
this.obj.style[key] = typeof obj[key] === 'number' ? obj[key] + 'px' : obj[key];
}
return this;
} ,
/** 设置放大 倍数*/
scale : function(scaleNumber){
this.css({
scale : scaleNumber
});
return this;
} ,
hasClass : function(cls) {
return this.obj.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
} ,
addClass : function(cls){
if (!this.hasClass(cls)) this.obj.className += " " + cls;
} ,
removeClass : function(cls) {
if (this.hasClass(cls)) {
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
this.obj.className = obj.className.replace(reg, ' ');
}
} ,
toggleClass : function(cls){
if(this.hasClass(cls)){
this.removeClass(cls);
}else{
this.addClass(cls);
}
} ,
// ------------------------ 动画 相关 ---------------------------------//
//TODO
animate : function(){
} ,
// ------------------------ 事件相关 ---------------------------------//
on : function(eventName,callback){
var $this = this;
this.obj['on' + eventName] = function(){
callback.call($this,$this.obj); //context指向$this,参数传入dom对象
};
return this;
} ,
// ------------------------ 属性相关 ---------------------------------//
attr : function(attr){
return this.obj.attributes[attr];
} ,
// ------------------------ ui ---------------------------------//
linkbutton : function(opts){
var opts = opts || {};
/**添加基本样式* */
this.addClass('linkbutton');
this.on('mouseover' , function(e){
//console.log(e);
this.css({
backgroundColor: '#d4ef50'
});
}).on('mouseout',function(e){
this.css({
backgroundColor: '#ac0'
});
});
opts.text && (this.obj.innerText = opts.text);
opts.click && (this.on('click' , opts.click));
}
}
}
win.$ = miniQuery;
})(window);
我没具体测试,如果发现目前代码中的bug,欢迎评论或者简信我哦 _ 。
本章结束 ...
剽悍一小兔,电气自动化毕业。
参加工作后对计算机感兴趣,深知初学编程之艰辛。
希望将自己所学记录下来,给初学者一点帮助。
免责声明: 博客中所有的图片素材均来自百度搜索,仅供学习交流,如有问题请联系我,侵立删,谢谢。