第八節(jié)dom以及dom庫的封裝

1锅移、獲取頁面中元素的方法
    document.getElementById()
    context.getElementsByTagName()
    context.getElementsByClassName() ie6~8不兼容
    document.getElementsByName()   應(yīng)用于表單中的name
    document.body
    document.documentElement
    context.querySelector/context.querySelectorAll ie6~8不兼容 通過這個獲取到的節(jié)點集合不存在dom映射

2晦雨、描述節(jié)點和節(jié)點之間關(guān)系的屬性(在標(biāo)準(zhǔn)瀏覽器中會把空格和換行當(dāng)做文本節(jié)點處理)
childNodes
children  在ie6~8下獲取的結(jié)果和標(biāo)準(zhǔn)瀏覽器獲取的結(jié)果不一致
parentNode
previousElementSibling/previousSibling
nextElementSibling/nextSibling
lastChild/lastElementChild
firstChild/firstElementChild


3、dom的增刪改
 createElement()
 document.createDocumentFragment()
 appendChild()
 insertBefore()
 cloneNode(true/false)
 replaceChild()
 removeChild()
 get/set/removeAttribute


4、dom盒子模型(參照第六節(jié))



什么是惰性思想恨锚?
使用惰性思想來封裝我的常用方法庫:第一次在給utils賦值的時候我們就已經(jīng)把兼容處理好了,把處理的結(jié)果存放在flag變量中,以后在每一個方法中,只要是ie6~8不兼容的,我們不需要重新檢測信殊,只需要使用flag的值即可比如以下:
var utils = (function () {
    var flag = "getComputedStyle" in window;
    return {
        listToArray: function (likeArray) {
            if (flag) {
                return Array.prototype.slice.call(likeArray);
            }
            var arr = [];
            for (var i = 0; i < likeArray.length; i++) {
                arr[arr.length] = likeArray[i];
            }
            return arr;
        }   
})();


以下的Dom庫封裝utils 方法庫完成了這些功能
1.獲取某一個容器中所有元素子節(jié)點(還可以篩選出指定簽名的)(function children)
2.獲取上一個哥哥元素節(jié)點(prev)、獲取下一個弟弟元素節(jié)點(next)汁果、獲取所有的哥哥元素節(jié)點(prevAll)涡拘、獲取所有弟弟元素節(jié)點(nextAll)、獲取相鄰的兩個元素節(jié)點(sibling)据德、獲取所有的兄弟元素節(jié)點(siblings)
4.獲取第一個元素子節(jié)點(firstChild)鳄乏、獲取最后一個元素子節(jié)點(lastChild)
5.獲取當(dāng)前元素的索引(index)
6.prepend增加到某一個容器開頭(和appendChild對應(yīng))
7.insertAfter增加到某一個元素后面(和inserBefore對應(yīng))
8.addClass增加樣式類名
9.removeClass 刪除樣式類名
10.hasClass判斷是否存在某一個樣式類名
11.解決getElementsByClassName()兼容問題
12.Jq中的css方法
11.getcss
12.setcss
13.getGroupCss


Dom庫封裝utils 方法庫
var utils = (function () {
    var flag = "getComputedStyle" in window;
    //獲取指定的子元素
    function children(objId, Ele) {
        var curary = [];
        if (!flag) {
            var childary = objId.childNodes;
            for (var i = 0; i < childary.length; i++) {
                if (childary[i].nodeType == 1) {
                    curary[curary.length] = childary[i];
                }
            }
            childary = null;
        } else {
            curary = this.listToArray(objId.children);
        }
        if (typeof Ele == "string") {
            for (var k = 0; k < curary.length; k++) {
                var curEle = curary[k];
                if (curEle.nodeName.toLowerCase() !== Ele.toLowerCase()) {
                    curary.splice(k, 1);
                    k--;
                }
            }
            curEle = null;
        }
        return curary;
    }

    //獲取上一個哥哥元素節(jié)點
    function prev(curEle) {
        if (flag) {
            return curEle.previousElementSibling;
        }
        var pre = curEle.previousSibling;
        while (pre && pre.nodeType != 1) {
            pre = pre.previousSibling;
        }
        return pre;
    }

    //獲取下一個弟弟節(jié)點
    function next(curEle) {
        if (flag) {
            return curEle.nextElementSibling;
        }
        var nextEle = curEle.nextSibling;
        while (nextEle && nextEle.nodeType != 1) {
            nextEle = nextEle.nextSibling;
        }
        return nextEle;
    }

    //獲取所有的哥哥節(jié)點
    function prevAll(curEle) {
        var ary = [];
        var pre = this.prev(curEle);
        while (pre) {
            ary.unshift(pre);
            pre = this.prev(pre);
        }
        return ary;
    }

    //獲取所有的弟弟節(jié)點
    function nextAll(curEle) {
        var pre = this.next(curEle);
        var ary = [];
        while (pre) {
            ary.push(pre);
            pre = this.next(pre);
        }
        return ary;
    }

    //獲取相鄰兩個元素節(jié)點
    function sibling(curEle) {
        var ary = [];
        var pre = this.prev(curEle);
        var next = this.next(curEle);
        pre ? ary.push(pre) : null;
        next ? ary.push(next) : null;
        return ary;
    }

    //獲取所有的兄弟節(jié)點
    function siblings(curEle) {
        return this.prevAll(curEle).concat(this.nextAll(curEle));
    }

    //獲取當(dāng)前元素索引
    function index(curEle) {
        return this.prevAll(curEle).length;
    }

    //第一個元素節(jié)點
    function firstChild(curEle) {
        var chs = this.children(curEle);
        return chs.length > 0 ? chs[0] : null;
    }

    //最后一個元素節(jié)點
    function lastChild(curEle) {
        var chs = this.children(curEle);
        return chs.length > 0 ? chs[chs.length - 1] : null;
    }

    //向容器中開頭追加新元素的方法
    function prepend(con, newEle) {
        var fir = this.firstChild(con);
        if (fir) {
            return con.insertBefore(newEle, fir);
        } else {
            return con.appendChild(newEle);
        }
    }

    //把新元素追加到指定元素之前
    function insertBefore(oldEle, newEle) {
        return oldEle.parentNode.insertBefore(newEle, oldEle);
    }

    //把元素追加到指定元素之后
    function insertAfter(oldEle, newEle) {
        var nex = this.next(oldEle);
        if (nex) {
            return oldEle.parentNode.insertBefore(newEle, nex);
        }
        return oldEle.parentNode.appendChild(newEle);
    }

    //類數(shù)組轉(zhuǎn)換成數(shù)組
    function listToArray(likeArray) {
        if (flag) {
            return Array.prototype.slice.call(likeArray);
        }
        var arr = [];
        for (var i = 0; i < likeArray.length; i++) {
            arr[arr.length] = likeArray[i];
        }
        return arr;
    }

    //json格式字符串轉(zhuǎn)換為json格式對象
    function jsonParse(str) {
        if (flag) {
            return JSON.parse(str);
        }
        return eval("(" + str + ")");
    }

    //檢測是否有class
    function hasClass(curEle, className) {
        var reg = new RegExp("(^| +)" + className + "( +|$)");
        return reg.test(curEle.className);
    }

    //增加class
    function addClass(curEle, className) {
        var ary = className.split(/ +/);
        for (var i = 0; i < ary.length; i++) {
            var cur = ary[i];
            if (!this.hasClass(curEle, cur)) {
                curEle.className += '' + cur;
            }
        }
    }

    //移出class
    function removeClass(curEle, className) {
        //先把首尾空格去掉,在拆分成數(shù)組
        var ary = className.replace(/^ +| +$/g, "").split(/ +/g);
        for (var i = 0; i < ary.length; i++) {
            var cur = ary[i];
            if (this.hasClass(curEle, cur)) {
                var reg = new RegExp("(^| +)" + cur + "( +|$)");
                curEle.className = curEle.className.replace(reg, ' ');
            }
        }
    }

    //getbyclass封裝
    function getclass(strClass, context) {
        context = context || document;
        var aryEle = context.getElementsByTagName('*');
        var aryCan = strClass.replace(/(^ +| +$)/g, "").split(/ +/);
        var ary = [];
        for (var i = 0; i < aryEle.length; i++) {
            var cur = aryEle[i];
            var isOkey = true;
            for (var k = 0; k < aryCan.length; k++) {
                var curk = aryCan[k];
                var reg = new RegExp("(^| +)" + curk + "($| +)");
                if (!reg.test(cur.className)) {
                    isOkey = false;
                    break;
                }
            }
            if (isOkey) {
                ary.push(cur);
            }
        }
        return ary;
    }

    //獲取樣式
    function getcss(attr) {
        var val = null;
        var reg = null;
        if (flag) {
            val = getComputedStyle(this)[attr];
        }
        else {
            if (attr = "opacity") {
                val = this.currentStyle["filter"];
                var reg = /^alpha\(opacity=(\d+(?:  \.\d+)?)\)$/;
                val = reg.test(val) ? reg.exec(val)[1] / 100 : 1;
            } else {
                val = this.currentStyle[attr];
            }
        }
        reg = /^(-?\d+(\.\d+)?)(em|rem|px)$/i;
        return reg.test(val) ? parseFloat(val) : val;
    }

    //設(shè)置css樣式
    function setcss(attr, value) {
//        在js中設(shè)置float樣式值的話棘利,也需要處理兼容
        if (attr == "float") {
            this["style"]["cssFloat"] = value;
            this["style"]["styleFloat"] = value;
            return;
        }
//        如果打算設(shè)置的是元素的透明度橱野,我們需要設(shè)置兩套樣式兼容所有的兼容
        if (attr == "opactity") {
            this["style"]["opactity"] = value;
            this["style"]["filter"] = "alpha(opacity=" + value * 100 + ")";
            return;
        }
        var reg = /^(width|height|top|bottom|left|right|((margin|padding)(Top|Bottom|Left|Right)?))$/;
        if (reg.test(attr) && !isNaN(value)) {
            value += "px";
        }
        this["style"][attr] = value;
    }

    //批量設(shè)置css樣式
    function setGroupCss(obj) {
        for (var k in  obj) {
            if (obj.hasOwnProperty(k)) {
                setcss.call(this, k, obj[k]);
            }
        }
    }

    //獲取、單獨設(shè)置赡译、批量設(shè)置
    function css(curEle) {
        //如果第三個參數(shù)存在就是設(shè)置仲吏,如果不存在就是獲取值
        var ary = Array.prototype.slice.call(arguments, 1);
        if (typeof arguments[1] == "string") {
            if (typeof  arguments[2] == "undefined") {
                return getcss.apply(curEle, ary);
            }
            return setcss.apply(curEle, ary);
        }
        if (Object.prototype.toString.call(arguments[1]) == "[object Object]") {
            return setGroupCss.apply(curEle, ary);
        }
    }

    return {
        listToArray: listToArray,
        jsonParse: jsonParse,
        children: children,
        prev: prev,
        next: next,
        prevAll: prevAll,
        nextAll: nextAll,
        sibling: sibling,
        siblings: siblings,
        index: index,
        firstChild: firstChild,
        lastChild: lastChild,
        prepend: prepend,
        insertBefore: insertBefore,
        insertAfter: insertAfter,
        hasClass: hasClass,
        addClass: addClass,
        removeClass: removeClass,
        getclass: getclass,
        css: css
    }
})();

1、基于dom庫封裝選項卡插件
~function () {
    function fn(container, deIndex) {
        var tabOption = utils.firstChild(container);
        var olis = utils.children(tabOption, "li");
        var divList = utils.children(container, "div");
        //讓deIndex對應(yīng)的頁卡有選中樣式
        utils.addClass(olis[deIndex], "active");
        utils.addClass(divList[deIndex], "active");
        //實現(xiàn)具體的切換功能
        for (var i = 0; i < olis.length; i++) {
            olis[i].onclick = function () {
                var sibEle = utils.siblings(this);
                var index = utils.index(this);
                for (var i = 0; i < sibEle.length; i++) {
                    utils.removeClass(sibEle[i], "active");
                }
                utils.addClass(this, "active");
                for (var i = 0; i < divList.length; i++) {
                    if (i != index) {
                        utils.removeClass(divList[i], "active");
                    } else {
                        utils.addClass(divList[i], "active");
                    }
                }
            };
        }
    }
    window.mytab = fn;
}();

2蝌焚、運用事件委托的方式完成選項卡插件封裝
~function () {
    function fn(container, deIndex) {
        var tabOption = utils.firstChild(container);
        var olis = utils.children(tabOption, "li");
        var divList = utils.children(container, "div");

        //讓deIndex對應(yīng)的頁卡有選中樣式
        utils.addClass(olis[deIndex], "active");
        utils.addClass(divList[deIndex], "active");

        tabOption.onclick = function (e) {
            e = e || window.event;
            e.target = e.target || e.srcElement;
            if (e.target.tagName.toLowerCase() == "li") {
                detailFn.call(e.target, divList, olis);
            }
        };
    }

    function detailFn(divList, olis) {
        var index = utils.index(this);
        for (var i = 0; i < divList.length; i++) {
            i === index ? (utils.addClass(divList[i], "active"), utils.addClass(olis[i], "active")) : (utils.removeClass(divList[i], "active"),
                utils.removeClass(olis[i], "active"));
        }
    }
    window.mytab = fn;
}();
3、運用面向?qū)ο蟮姆绞椒庋b選項卡插件
~function () {
    function TabChange(container, deIndex) {
        this.init(container, deIndex);
    }
    TabChange.prototype = {
        constructor: TabChange,
        //按照索引來設(shè)置默認(rèn)選中的頁卡
        defaultIndexEvent: function () {
            utils.addClass(this.olis[this.deIndex], "active");
            utils.addClass(this.divList[this.deIndex], "active");
        },
        //事件委托實現(xiàn)綁定切換
        liveClick: function () {
            var _this = this;
            this.tabOption.onclick = function (e) {
                e = e || window.event;
                e.target = e.target || e.srcElement;
                if (e.target.tagName.toLowerCase() == "li") {
                    _this.detailFn(e.target);
                }
            }
        },
        detailFn: function (curEle) {
            var index = utils.index(curEle);
            for (var i = 0; i < this.divList.length; i++) {
                i === index ? (utils.addClass(this.divList[i], "active"), utils.addClass(this.olis[i], "active")) : (utils.removeClass(this.divList[i], "active"),
                    utils.removeClass(this.olis[i], "active"));
            }
        },
        //初始化誓斥,也是當(dāng)前插件的唯一入口
        init: function (container, deIndex) {
            this.container = container || null;
            this.deIndex = deIndex || 0;
            this.tabOption = utils.firstChild(container);
            this.olis = utils.children(this.tabOption, "li");
            this.divList = utils.children(container, "div");
            this.defaultIndexEvent();
            this.liveClick();
        }
    };
    window.mytab = TabChange;
}();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末只洒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子劳坑,更是在濱河造成了極大的恐慌毕谴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件距芬,死亡現(xiàn)場離奇詭異涝开,居然都是意外死亡,警方通過查閱死者的電腦和手機框仔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進(jìn)店門舀武,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人离斩,你說我怎么就攤上這事银舱。” “怎么了跛梗?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵寻馏,是天一觀的道長。 經(jīng)常有香客問我核偿,道長诚欠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮轰绵,結(jié)果婚禮上粉寞,老公的妹妹穿的比我還像新娘。我一直安慰自己藏澳,他們只是感情好仁锯,可當(dāng)我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著翔悠,像睡著了一般业崖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓄愁,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天双炕,我揣著相機與錄音,去河邊找鬼撮抓。 笑死妇斤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丹拯。 我是一名探鬼主播站超,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼乖酬!你這毒婦竟也來了死相?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤咬像,失蹤者是張志新(化名)和其女友劉穎算撮,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體县昂,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡肮柜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了倒彰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片审洞。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狸驳,靈堂內(nèi)的尸體忽然破棺而出预明,到底是詐尸還是另有隱情,我是刑警寧澤耙箍,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布撰糠,位于F島的核電站,受9級特大地震影響辩昆,放射性物質(zhì)發(fā)生泄漏阅酪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望术辐。 院中可真熱鬧砚尽,春花似錦、人聲如沸辉词。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瑞躺。三九已至敷搪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幢哨,已是汗流浹背赡勘。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捞镰,地道東北人闸与。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像岸售,于是被迫代替她去往敵國和親践樱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,499評論 2 348

推薦閱讀更多精彩內(nèi)容