JavaScript 模块化开发

🌙
手机阅读
本文目录结构

用封装好的DOM库,模块化开发选项卡

封装好的DOM库来实现模块化开发选项卡

第一次封的模块化现象卡,借助封装的DOM库

后面还在在这两次的基础上,再次进行模块化开发;

封装思路是,先获取指定的li集合;

然后鼠标操作li,通过DOM关系来间接操作下面的DIV部分;

这次的模块化开发中,class=“select"与方法耦合了;下次封装的时候;需要分离开来;

后面会再次重新封装;

代码

html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>JavaScript模块化开发选项卡</title>
    <link rel="stylesheet" href="css/tabModel.css"/>
</head>
<body>
<div class="tabModel">
    <ul class="tabHeads" id="tabHeads">
        <li class="tabHead1 selectTabHead highlight">选项1</li>
        <li class="tabHead2">选项2</li>
        <li class="tabHead3">选项3</li>
        <li class="tabHead4">选项4</li>
        <li class="tabHead5">选项5</li>
    </ul>
    <div class="tabContents">
        <div class="tabContent1 selectTabContent"><p>模块化开发,把一个效果分为不同的DOM库模块;以后可以加快开发力度;</p></div>
        <div class="tabContent2">朱安邦002</div>
        <div class="tabContent3">朱安邦003</div>
        <div class="tabContent4">朱安邦004</div>
        <div class="tabContent5">朱安邦005</div>
    </div>
</div>
<!--分界线-->
<div class="tabModel">
    <ul class="tabHeads" id="tabHeads2">
        <li class="tabHead selectTabHead highlight">选项1</li>
        <li class="tabHead">选项2</li>
        <li class="tabHead">选项3</li>
        <li class="tabHead">选项4</li>
        <li class="tabHead">选项5</li>
    </ul>
    <div class="tabContents">
        <div class="tabContent selectTabContent"><p>模块化开发,把一个效果分为不同的DOM库模块;以后可以加快开发力度;</p></div>
        <div class="tabContent">朱安邦002</div>
        <div class="tabContent">朱安邦003</div>
        <div class="tabContent">朱安邦004</div>
        <div class="tabContent">朱安邦005</div>
    </div>
</div>
<!--分界线-->
<div class="tabModel">
    <ul class="tabHeads" id="tabHeads3">
        <li class="tabHead selectTabHead highlight">选项1</li>
        <li class="tabHead">选项2</li>
        <li class="tabHead">选项3</li>
        <li class="tabHead">选项4</li>
        <li class="tabHead">选项5</li>
    </ul>
    <div class="tabContents">
        <div class="tabContent selectTabContent"><p>模块化开发,把一个效果分为不同的DOM库模块;以后可以加快开发力度;</p></div>
        <div class="tabContent">朱安邦002</div>
        <div class="tabContent">朱安邦003</div>
        <div class="tabContent">朱安邦004</div>
        <div class="tabContent">朱安邦005</div>
    </div>
</div>
<!--分界线-->
<script src="js/tool.js"></script>
<script src="js/index.js"></script>
</body>
</html>

css

div,ul,li{
    padding: 0;
    margin: 0;
    font-size: 16px;
    font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif;
}
ul,li{
    list-style: none;
}
.tabModel{
    width: 600px;
    height: 500px;
    border:1px solid #ccc ;
    border-radius: 5px;
    margin: 10px auto;
    padding: 5px;
}
.tabHeads{position: relative;top: 1px}
.tabHead1{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: orange;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}
.tabHead2{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: #37C7D4;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}
.tabHead3{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: #E44072;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}
.tabHead4{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: #cccccc;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}
.tabHead5{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: #00FF00;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}



.tabContent1{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: orange;
    clear: both;
    display: none;
}
.tabContent2{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: #37C7D4;
    clear: both;
    display: none;
}
.tabContent3{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: #E44072;
    clear: both;
    display: none;
}
.tabContent4{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: #37C7D4;
    clear: both;
    display: none;
}
.tabContent5{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: #00FF00;
    clear: both;
    display: none;
}

/*第二模块*/
.tabHead{
    width: 60px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid red ;
    background: brown;
    float: left;
    margin-right:10px ;
    cursor: pointer;
}
.tabContent{
    width: 100%;
    height: 465px;
    line-height: 465px;
    text-align: center;
    border: 1px solid red ;
    background: blanchedalmond;
    clear: both;
    display: none;
}

.highlight{color: #00FF00 }
.selectTabHead{background: #000000;color: #FFFFFF;}
.selectTabContent{display: block}

js

//Tools

var Tool = function () {//构造函数模式;用的时候需要new一下;
    this.flag = "getElementsByClassName" in document;
    //getElementsByClassName 在IE678中是不存在的。用这个来判断是不是低版本的IE浏览器;
    //每次只需要判断this.flag是否存在就可以了;如果存在就是标准浏览器,如果不存在就是IE;
};
Tool.prototype = {//方法是定义在Tool的prototype上的;
    constructor: Tool,//重写prototype后,prototype的constructor已经不是原来的Tool了;需要手动给他强制写会到Tool上去;
    /*经常用到的函数*/
    getElementsByClassName: function (context,cName) {//获取元素的ClassName
        var context = context || document;
        var ary = [];
        if (this.flag) {
            return context.getElementsByClassName(cName);
        }
        var allNode = context.getElementsByTagName("*");
        var reg = new RegExp("(?:^| +)" + cName + "(?: +|$)");
        for (var i = 0; i < allNode.length; i++) {
            var cur = allNode[i];
            if (reg.test(cur.className)) {
                ary.push(cur);
            }
        }
        return ary;
    },
    toJSON: function (jsonStr) {//将json字符串转化为json对象
        var jsonObj = null;
        try {
            jsonObj = JSON.parse(jsonStr);//如果支持 JSON.parse则直接使用 JSON.parse将JSON字符串转换为JSON对象。
        } catch (e) {
            jsonObj = eval("(" + jsonStr + ")");
        }
        return jsonObj;
    },
    isType: function (value,type) {//判断数据类型;
        var type = arguments[1] || "Object",
            reg = new RegExp("\\[object " + type + "\\]", "i");
        return reg.test({}.toString.call(value));//{}不可以是[],因为[]就不是Object.prototype,数组也有toString方法;
    },
    listToArray: function (likeAry) {//类数组转化为数组;
        var ary = [];
        if (this.flag) {
            ary = [].slice.call(likeAry, 0);
        } else {
            for (var i = 0; i < likeAry.length; i++) {
                ary.push(likeAry[i]);
            }
        }
        return ary;
    },

    /***下面是设置DOM***/
    getEleChildren: function (parent,tagName) {//获取指定节点名的元素节点们;第二个参数如果不传,则返回obj下的所有子元素节点;
        var allNode = parent.childNodes,
            ary = [],
            reg = new RegExp("^" + tagName + "$", "i");
        for (var i = 0; i < allNode.length; i++) {
            var cur = allNode[i];
            if (cur.nodeType === 1) {
                if (tagName) {//tahName不可能为0,false之类的数;所以可以用if直接判断传进来的参数;
                    if (reg.test(cur.nodeName)) {
                        ary.push(cur);
                    }
                    continue;
                }
                ary.push(cur);
            }
        }
        return ary;
    },
    getFirst: function (curEle) {//获取第一个元素节点;
        var children = this.getEleChildren(curEle);
        return children.length > 0 ? children[0] : null;
    },
    getLast: function (curEle) {//获取最后一个元素节点;
        var children = this.getEleChildren(curEle);
        return children.length > 0 ? children[children.length - 1] : null;
    },
    getPre: function (curEle) {//上一个哥哥节点;
        if (this.flag) {
            return curEle.previousElementSibling;
        }
        var pre = curEle.previousSibling;
        while (pre && pre.nodeType !== 1) {
            pre = pre.previousSibling;
        }
        return pre;
    },
    getPres: function (curEle) {//获得所有哥哥们;
        /*            var ary = [],
         attr = this.flag ? "previousElementSibling" : "previousSibling";
         var pre = curEle[attr];
         while (pre) {
         if (pre.nodeType === 1) {
         ary.unshift(pre);
         }
         pre = pre[attr];
         }
         return ary;*/
        var ary = [],
            next = this.getPre(curEle);
        while (next) {
            ary.unshift(next);
            next = this.getPre(next);
        }
        return ary;
    },
    getNext: function (curEle) {//下一个弟弟节点,第一个弟弟节点;
        if (this.flag) {
            return curEle.nextElementSibling;
        }
        var next = curEle.nextSibling;
        while (next && next.nodeType !== 1) {
            next = next.nextSibling;
        }
        return next;
    },
    getNexts: function (curEle) {//获取所有的弟弟们;
        var ary = [],
            next = this.getNext(curEle);
        while (next) {
            ary.push(next);
            next = this.getNext(next);
        }
        return ary;
    },
    getSibling: function (curEle) {//获取上一个哥哥和下一个弟弟;
        var ary = [],
            pre = this.getPre(curEle),
            next = this.getNext(curEle);
        pre ? ary.push(pre) : void 0;
        next ? ary.push(next) : void 0;
        return ary;
    },
    getSiblings: function (curEle) {//获取所有的兄弟们(除了自己)
        var pres = this.getPres(curEle),
            nexts = this.getNexts(curEle);
        return pres.concat(nexts);
    },
    getIndex: function (curEle) {//获取元素的索引值;
        return this.getPres(curEle).length;
    },
    insertAfter: function (newEle,oldEle) {//在目标元素oldEle后面插入新元素newEle;如果没有传指定元素,则直接添加在后面
        var next = this.getNext(oldEle),
            par = oldEle.parentNode;
        next ? par.insertBefore(newEle, next) : par.appendChild(newEle);
    },
    prependChild: function (parentEle,curEle) {//把一个元素节点添加为parentEle的第一个子节点;
        var first = this.getFirst(parentEle);//获取par中的第一个元素节点;
        first ? parentEle.insertBefore(curEle, first) : parentEle.appendChild(curEle);
    },
    innerHTML: function (curEle,str) {//获取元素的innerHTML;
        var str= str || "";
        if (!str) {
            return curEle.innerHTML;
        }
        curEle.innerHTML = str;
    },

    /***下面是设置CSS***/
    setCss: function (curEle,attr,value) {//设置CSS属性值和获取CSS;如果三个参数就是设置,2个参数就是获取;att是attribute的缩写;
        if( typeof value =="String"){//如果有第三个参数,就是设置Css;如果没有就是获取Css;
            switch (attr) {
                case "opacity":
                    curEle["style"][attr] = value;
                    curEle["style"]["filter"] = "alpha(opacity=" + (value * 100) + ")";
                    break;
                case "zIndex":
                    curEle["style"][attr] = value;
                    break;
                default:
                    curEle["style"][attr] = !isNaN(value) ? value += "px" : value;
            }
        }
        var reg = /^(?:margin|padding|border|float|position|display|background|backgroundColor)$/;
        var value = this.flag ? window.getComputedStyle(curEle, null)[attr] : curEle.currentStyle[attr];
        return !reg.test(attr) ? parseFloat(value) : value;//如果是width之类数值;就转成数字返回;如果是background类型的直接返回value;
    },
    setGroupCss: function (curEle,cssObj) {//给元素设置一组属性;cssObj是一个对象类型;
        for (var key in cssObj) {
            this.setCss(curEle, key, cssObj[key]);
        }
    },
    offset: function (curEle) {//获取偏移量;
        var  par = curEle.offsetParent,
            left = curEle.offsetLeft,
            top = curEle.offsetTop;
        while (par) {
            left += par.offsetLeft;
            top += par.offsetTop;
            if (navigator.userAgent.indexOf("MSIE 8.0") <= -1) {
                left += par.clientLeft;
                top += par.clientTop;
            }
            par = par.offsetParent;
        }
        return {left: left, top: top};
    },
    hasClassName: function (curEle,cName) {//判断是否有某个className;
        var reg = new RegExp("(?:^| +)" + cName + "(?: +|$)");
        return reg.test(curEle.className);
    },
    addClassName: function (curEle,cName) {//增加某个className;
        if (!this.hasClassName(curEle,cName)) {
            curEle.className += (" " + cName);
        }
    },
    removeClassName: function (curEle,cName) {//移除类样式的方法;
        var reg = new RegExp("(?:^| +)" + cName + "(?: +|$)", "g");
        if (this.hasClassName(curEle,cName)) {
            curEle.className = curEle.className.replace(reg, " ");
        }
    }
};
~function () {//在DOM库上增加方法,同时不影响原来的方法;在类的原型上增加方法;
    var strPro = String.prototype,
        aryPro = Array.prototype,
        objPro = Object.prototype;
    aryPro.removeRepeat = function () {//数组去重;
        var obj = {};
        for (var i = 0; i < this.length; i++) {
            var cur = this[i];
            if (obj[cur] == cur) {
                this.splice(i, 1);
                i--;
                continue;
            }
            obj[cur] = cur;
        }
        obj = null;
        return this;
    };
    aryPro.forEachPro = function (fn,context) {//forEach兼容性处理;
        var context = context || window;
        if (this.forEach) {
            this.forEach(fn, context);
            return this;
        }
        for (var i = 0; i < this.length; i++) {
            fn.call(context, this[i], i, this);
        }
        return this;
    };
    objPro.myHasPubProperty = function (attr) {//是否为公有属性;
        return (attr in this) && !this.hasOwnProperty(attr);
    };
    strPro.myTrim = function () {//去除首尾空格;
        return this.replace(/(^\s*|\s*$)/g, "");
    };
    strPro.mySub = function (len,isD) {//是不是有效的
        var len = len || 10,
            isD = isD || false,
            str = "",
            n = 0;
        for (var i = 0; i < this.length; i++) {
            var s = this.charAt(i);
            /[\u4e00-\u9fa5]/.test(s) ? n += 2 : n++;
            if (n > len) {
                isD ? str += "..." : void 0;
                break;
            }
            str += s;
        }
        return str;
    };
    strPro.myFormatTime = function (format) {//时间格式化;
        var reg = /^(\d{4})(?:-|\/|\.|:)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})(?:\s+)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})(?:-|\/|\.|:)(\d{1,2})$/g,
            ary = [];
        this.replace(reg, function () {
            ary = ([].slice.call(arguments)).slice(1, 7);
        });
        var format = format || "{0}年{1}月{2}日 {3}:{4}:{5}";
        return format.replace(/{(\d+)}/g, function () {
            var val = ary[arguments[1]];
            return val.length === 1 ? "0" + val : val;
        });
    };
    strPro.myQueryURLParameter = function () {//是否是有效URL
        var reg = /([^?&=]+)=([^?&=]+)/g, obj = {};
        this.replace(reg, function () {
            obj[arguments[1]] = arguments[2];
        });
        return obj;
    }
}();
var t=new Tool();
var tabHeads=document.getElementById("tabHeads"),
    oLis= tabHeads.getElementsByTagName("li");
for(var i= 0,len=oLis.length;i<len;i++){
    oLis[i].onmouseover=tabChange;
}
var tabHeads2=document.getElementById("tabHeads2"),
    oLis2= tabHeads2.getElementsByTagName("li");
for(var j= 0,len2=oLis2.length;j<len2;j++){
    oLis2[j].onmouseover=tabChange;
}
var tabHeads3=document.getElementById("tabHeads3"),
    oLis3= tabHeads3.getElementsByTagName("li");
for(var j= 0,len3=oLis3.length;j<len3;j++){
    oLis3[j].onmouseover=tabChange;
}
function tabChange(){
    var n=t.getIndex(this);//获取当前元素的索引号;

    var siblings= t.getSiblings(this);//获取当前元素的兄弟们;
    for(var i= 0,len=siblings.length;i<len;i++){
        t.removeClassName(siblings[i],"selectTabHead");//清除当前选中tabHead兄弟们的selectTabHead属性;
    };

    var parent=this.parentNode;//获取当前元素的父级节点;
    var next=t.getNext(parent);//获取当前元素父级节点的下一个兄弟节点;
    var contents=t.getEleChildren(next,"div");//获取当前元素父节点下的所有元素子节点;
    for(var i= 0,len=contents.length;i<len;i++){
        t.removeClassName(contents[i],"selectTabContent");//删除节点的selectTabContent属性;
    }
    t.addClassName(this,"selectTabHead");//被点击元素添加tabSelectHead的class字符串;
    t.addClassName(contents[n],"selectTabContent");
    console.log(n);
}

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了