js简介(插件封装解析)

弹窗插件

function Popover(options){
    //1.设置默认值,与传进来的对下那个进行合并
    var defaults = {
        width:600,
        height:'auto',//可以是数值
        position:'center',//可以传进来对象{x,y}
        title:'弹窗标题',
        content:'',
        draggable:true,
        overlay:0.3 //数字:有遮罩层,false:无遮罩层
    }
    var opt = Object.assign({},defaults,options);
    this.position = opt.position;
    this.init(opt);
}
Popover.prototype = {
    init(opt){
        //2.初始化方法:
        //(1)创建弹窗this.ele,设置宽高
        this.ele = document.createElement('div');
        this.ele.className = 'popover';
        this.ele.style.width = opt.width + 'px';
        if(typeof opt.height === 'number'){
            this.ele.style.height = opt.height + 'px';
        }
        //(2)标题和内容(设置类名title、content)
        var title = document.createElement('div');
        title.className = 'title';
        title.innerHTML = opt.title;
        this.ele.appendChild(title);
        var content = document.createElement('div');
        content.className = 'content';
        content.innerHTML = opt.content;
        this.ele.appendChild(content);
        // (3)遮罩层(判断overlay是数字则为透明度,为false则不设置遮罩层)(类名、透明度)
        if(opt.overlay !== false){
            this.bg = document.createElement('div');
            this.bg.className = 'overlay';
            this.bg.style.opacity = opt.overlay;
            document.body.appendChild(this.bg);
        }
        // (4)删除按钮(类名、内容)
        var btnClose = document.createElement('span');
        btnClose.className = 'btn-close';
        btnClose.innerHTML = '×';
        this.ele.appendChild(btnClose);
        // (5)弹窗写入页面,并显示弹窗
        document.body.appendChild(this.ele);
        this.show();
        // (6)设置关闭事件
        btnClose.onclick = function(){
            this.close();
        }.bind(this);
        //(7)拖拽
        if(opt.draggable){
            this.drag();
        }
    },
    //3.1显示:设置成块,同时调用定位方法
    show(){
        this.ele.style.display = 'block';
        if(this.bg){
            this.bg.style.display = 'block';
        }
        this.setPosition();
    },
    //3.2隐藏:
    close(){
        this.ele.style.display = 'none';
        if(this.bg){
            this.bg.style.display = 'none';
        }
    },
    //4.定位:判断是否传参
    //(1)若没有参数,即x值为undefined,则判断this.postion的值为center还是对象,设置x、y值
    //(2)给元素设置样式
    setPosition(x,y){
        if(x===undefined){
            // 如果元素没有添加(并显示)到页面,获取不到宽高
            if(this.position === 'center'){
                x = (window.innerWidth - this.ele.offsetWidth)/2;
                y = (window.innerHeight - this.ele.offsetHeight)/2;
            }else if(typeof this.position === 'object'){
                x = this.position.x;
                y = this.position.y;
            }
        }
        this.ele.style.left = x + 'px';
        this.ele.style.top = y + 'px';
    },    
    //5.拖拽
    drag(){
        var self = this;
        var pop = self.ele;
        pop.onmousedown = e=>{
            var ox = e.clientX - pop.offsetLeft;
            var oy = e.clientY - pop.offsetTop;
            // 只能在标题位置拖拽
            if(oy>pop.children[0].offsetHeight){
                return;
            }
            document.onmousemove = function(evt){
                var x = evt.clientX - ox;
                var y = evt.clientY - oy;
                self.setPosition(x,y);
                evt.preventDefault();
            }
        }
        document.onmouseup = function(){
            document.onmousemove = null;
        }
    }

弹窗继承

//确认对话框
function Confirm(options){
    var defaults = {
        width:300,
        title:false,
        content:'你确定这个操作吗',
        overlay:false,
        confirm:function(){},
        cancel:function(){}
    }
    var opt = Object.assign({},defaults,options);
    //1.借用构造函数,拿到弹窗对象属性this.ele及this.position
    Popover.call(this,opt);
}
// 2.继承Popover的方法
Confirm.prototype = Object.create(Popover.prototype);
//3.添加/重置方法
Confirm.prototype.init = function(opt){
    //3.1把你需要的部分复制下来
    //3.2添加确认取消按钮
    this.confirmBtn = document.createElement('button');
    this.confirmBtn.className = 'btn-confirm';
    this.confirmBtn.innerText = '确认';

    this.cancelBtn = document.createElement('button');
    this.cancelBtn.className = 'btn-cancel';
    this.cancelBtn.innerText = '取消';
    this.ele.appendChild(this.confirmBtn);
    this.ele.appendChild(this.cancelBtn);

    // 3.3点击确认取消按钮,执行方法
    this.confirmBtn.onclick = ()=>{
        opt.confirm();
        this.close();
    }
    this.cancelBtn.onclick = ()=>{
        opt.cancel();
        this.close();
    }

时间格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
if(!Date.prototype.format){
Date.prototype.format = function(fmt){
//fmt格式:“YYYY-MM-DD hh:mm:ss”
var o = {
"M+" : this.getMonth()+1,
"D+" : this.getDate(),
"h+" : this.getHours(),
"m+" : this.getMinutes(),
"s+" : this.getSeconds()
};
if(/(Y+)/.test(fmt)){
var res = String(this.getFullYear()).substr(4-RegExp.$1.length);
fmt = fmt.replace(RegExp.$1,res);
}
for(var str in o){
var reg = new RegExp('('+str+')');
if(reg.test(fmt)){
var res = RegExp.$1.lenth>1? ("00"+o[str]).substr(String(o[str]).length) : o[str];
//9===>009.substr(1)
//0012===>0012.substr(2)
fmt = fmt.replace(RegExp.$1,res);
}
}
return fmt;
}
}
1
2
3
4
5
6
7
var str = "X98Y87Z65";
// 三个数字部分加了小括号,表示子表达式
var reg = /^X(\d+)Y(\d+)Z(\d+)$/;
reg.test(str); // 此处使用exec()等其他正则表达式的匹配方法也可,下同
document.writeln(RegExp.$1); // 98
document.writeln(RegExp.$2); // 87
document.writeln(RegExp.$3); // 65

简化DOM节点操作

1
2
3
4
5
6
7
8
9
10
* 面向对象的DOM操作
* show():显示
* hide():隐藏
* on():事件绑定
* css():获取/设置Css样式
* addClass():添加类名
* removeClass():移除类名
* attr():获取/设置html属性值
* html():设置/获取html内容
* text():设置/获取文本内容
class xJquery{
    // 1.this.ele获取初始化
    constructor(selector){
        // 1.1若不是传入字符串,则可能传入DOM节点(判断选择器的标签名是否存在)或类数组Array。
        // this.ele得到值,退出该函数
        if(typeof selector != 'string'){
            if(selector.tagName){
                this.ele = [selector];
            }else{
                this.ele = selector;
            }
            return;
        }
        //1.2若传入的是选择器
        try{
            this.ele  = document.querySelectorAll(selector);//Nodelist
        }catch(error){
            var selectorName = selector.slice(1);
            if(/^#/.test(selector)){
                //变成数组为的是后面的遍历
                this.ele = [document.getElementById(selectorName)];//Array
            }else if(/^\./.test(selector)){
                try{
                    this.ele = document.getElementsByClassName(selectorName);//HTMLCollection
                }catch(err){
                    this.ele = [];
                    var res = document.getElementByTagName('*');
                    for(var i=0;i<res.length;i++){
                        var className = res[i].className.split(' ');
                        if(className.indexOf(selectorName)>=0){
                            this.ele.push(res[i]);
                        }
                    }
                }
            }else{
                //getElementsByTagName
                this.ele = document.getElementsByTagName(selector);
            }
        }
    }
    //2.显示隐藏方法
    show(){
        Array.prototype.forEach.call(this.ele,function(ele){
            ele.style.display = 'block';
        });
        // 方便链式调用
        return this;
    }
    hide(){
        Array.prototype.forEach.call(this.ele,function(ele){
            ele.style.display = 'none';
        });
        return this;
    }
    // 3.事件绑定
    on(type,handler,isCapture){
        Array.prototype.forEach.call(this.ele,function(ele){
            try{
                ele.addEventListener(type,handler,isCapture)
            }catch(error){
                try{
                    ele.attachEvent('on' + type,handler);
                }catch(err){
                    ele['on'+type] = handler;
                }
            }
        });
        return this;
    }
    // 4.获取/设置Css样式
    css(key,value){
        // 若没有传入value,则代表获取值,只获取第一个元素的值
        if(value === undefined){
            if(window.getComputedStyle){
                return getComputedStyle(this.ele[0])[key]
            }else if(this.ele[0].currentStyle){
                return this.ele[0].currentStyle[key]
            }else{
                return this.ele[0].style[key]
            }
        }
        // 设置,则设置所有元素的值
        Array.prototype.forEach.call(this.ele,function(ele){
            ele.style[key] = value;
        })
        return this;
    }
    // 5.给所有元素添加类名
    addClass(name){
        Array.prototype.forEach.call(this.ele,function(ele){
            try{
                ele.classList.add(name);
            }catch(error){
                var className = ele.className.split(' ');
                if(className.indexOf(name) == -1){
                    className.push(name);
                }
                ele.className = className.join(' ');
            }
        })
    }
    // 6.移除所有元素的该类名
    removeClass(name){
        Array.prototype.forEach.call(this.ele,function(ele){
            ele.classList.remove(name)
        });
    }
    // 7.设置/获取html内容
    html(html){
        // 获取第一个元素的html内容
        if(html === undefined){
            return this.ele[0].innerHTML
        }
        // 设置所有元素的html内容
        Array.prototype.forEach.call(this.ele,function(ele){
            ele.innerHTML = html;
        });
        return this;
    }
    // 设置/获取文本内容
    text(txt){}
}
//执行$(selector),返回实例对象
let $ = function(selector){
    return new xJquery(selector);
}