JavaScript實現選項卡功能(面向過程與面向對象)

面向過程

註意:

ul>li 標簽屬性中 的index屬性值是串聯起ol>li與ul>li的關鍵,通過調用相同索引下標的數組中的不同屬性的屬性值達到切換內容的效果。

通過事件委托找到對應的ul>li 進行css屬性的刪除與新增做到背景顏色改變和內容改變的效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
 
        ul,ol,li{
            list-style: none;
        }
 
        .box{
            width: 800px;
            height: 600px;
            border: 3px solid #000;
            margin: 50px auto;
            display: flex;
            flex-direction: column;
 
        }
 
        .box > ul{
            width: 100%;
            height: 100px;
            display: flex;
  
        }
 
        .box > ul >li{
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 50px;
            background: pink;
            border-right: 2px solid #000;
            border-bottom: 2px solid #000;
            color: #fff;
 
        }
 
        .box > ul >li:last-child{
            border-right: none;
        }
 
        .box > ul >li.active{
            color: red;
            text-decoration: underline;
            background: orange;
        }
 
 
        .box > ol {
            flex: 1;
            position: relative;
 
        }
 
        .box > ol >li{
            width: 100%;
            height: 100%;
            position: absolute;
            top:0;
            left: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            background: cyan;
            display: none;
            color: #fff;
        }
 
        .box > ol > li.active{
            display: flex;
        }
 
    </style>
</head>
<body>
 
    <div class="box"></div>
   
    <script>
        // 面向過程 
 
        // 定義數組 模擬數據庫數據
        var arr1 = [
            { id:1 , ulLi:'精選' , olLi:'精選內容' },
            { id:2 , ulLi:'美食' , olLi:'美食內容' },
            { id:3 , ulLi:'百貨' , olLi:'百貨內容' },
            { id:4 , ulLi:'個護' , olLi:'個護內容' },
        ];
 
 
        // 獲取標簽對象 
        const oBox = document.querySelector('.box');
 
        // 定義全局變量儲存數據
        let oUlLis ;
        let oOlLis ;
 
        // 調用函數 動態渲染生成頁面
        setPage();
 
        // 調用函數 添加事件
        setEvent();
 
        // 定義函數1 動態生成頁面
        function setPage(){
            // 創建固定的標簽節點 ul ol 
            const oUl = document.createElement('ul');
            const oOl = document.createElement('ol');
 
            // 定義字符串 存儲動態渲染生成的ul>li ol>li
            let ulLiStr = '';
            let olLiStr = '';
 
            // 循環遍歷數組 根據數組中的內容動態渲染生成li標簽
            arr1.forEach( function(item,key){
                // item 是 數組單元存儲的數據 也就是 存儲數據的對象
                // key 是 數組單元的索引下標
 
                // 第一個ul>li 有 class,active樣式
                ulLiStr += key === 0 ? `<li name="ulLi" index="${key}" class="active">${item.ulLi}</li>` : `<li index="${key}" name="ulLi">${item.ulLi}</li>` ;
 
                // 第一個ol>li 有 class,active樣式
                olLiStr += key === 0 ? `<li class="active">${item.olLi}</li>` : `<li>${item.olLi}</li>` ;
            });
 
            console.log( ulLiStr );
            console.log( olLiStr );
 
            // 將字符串寫入ul ol 標簽
            oUl.innerHTML = ulLiStr ;
            oOl.innerHTML = olLiStr ;
 
            // 將 ul ol 標簽 寫入 div標簽中
            oBox.appendChild( oUl );
            oBox.appendChild( oOl );
 
            // 獲取所有的ul>li
            oUlLis = oUl.querySelectorAll('li');
 
            // 獲取所有的ol>li
            oOlLis = oOl.querySelectorAll('li');
 
        }
 
        // 定義函數2 給標簽添加事件
        // 參數 綁定事件的事件類型 可以是click mouseover 默認值是 mouseover
        function setEvent( event = 'mouseover' ){
            // 給 父級標簽 添加 事件 通過事件委托完成效果
            oBox.addEventListener( event , function(e){
                if( e.target.getAttribute('name') === 'ulLi' ){
                    // 清除所有 ul>li 的 class,active
                    oUlLis.forEach( function(item , key){
                        // item 是 ul>li中 li標簽對象
                        // key 是 ul>li中 li標簽對象的索引下標
                        // 同時也是 ol>li中 li標簽對象的索引下標 
                        item.classList.remove('active');
 
                        // key是ul>li的索引下標 也就是ol>li的索引下標
                        // oOlLs數組可以通過索引下標 獲取到 ol>li標簽對象
                        oOlLis[key].classList.remove('active');
                    })
 
                    // 給觸發事件的ul>li標簽添加class,active
                    e.target.classList.add('active');
 
                    // 給觸發事件的ul>li標簽 對應的ol>li標簽添加class,active
                    // 也就是和 e.target 觸發事件標簽 索引下標相同的 ol>li標簽
                    // 也就是獲取 e.target標簽 index屬性的屬性值
                    // 標簽屬性的屬性值 都是 字符串類型 需要轉化為數值類型
                    oOlLis[ Number( e.target.getAttribute('index') ) ].classList.add('active');
 
                }
            })
        }
 
    </script>
 
</body>
</html>

面向對象 

註意:

  • 之前調用的是變量,現在調用的是對象中存儲的屬性與屬性值 。
  • 確保 this 的指向是對象,當事件綁定 forEach 定時器延時器… 中 this指向 會改變
  • 修改this指向的方法:提前使用變量 存儲 原始this指向,使用 變量 替代 this關鍵詞

 代碼展示:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
 
        ul,
        ol,
        li {
            list-style: none;
        }
 
        .box {
            width: 800px;
            height: 600px;
            border: 3px solid #000;
            margin: 50px auto;
            display: flex;
            flex-direction: column;
 
        }
 
        .box>ul {
            width: 100%;
            height: 100px;
            display: flex;
 
        }
 
        .box>ul>li {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 50px;
            background: pink;
            border-right: 2px solid #000;
            border-bottom: 2px solid #000;
            color: #fff;
 
        }
 
        .box>ul>li:last-child {
            border-right: none;
        }
 
        .box>ul>li.active {
            color: red;
            text-decoration: underline;
            background: orange;
        }
 
 
        .box>ol {
            flex: 1;
            position: relative;
 
        }
 
        .box>ol>li {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            background: cyan;
            display: none;
            color: #fff;
        }
 
        .box>ol>li.active {
            display: flex;
        }
    </style>
</head>
 
<body>
 
    <div class="box"></div>
    <!-- 導入外部文件 -->
    <script src="./tab.js"></script>
    <script>
        // 定義數組 模擬數據庫數據
        const arr1 = [
            { id: 1, ulLi: '精選', olLi: '精選內容' },
            { id: 2, ulLi: '美食', olLi: '美食內容' },
            { id: 3, ulLi: '百貨', olLi: '百貨內容' },
            { id: 4, ulLi: '個護', olLi: '個護內容' },
        ];
 
 
        // 獲取標簽對象 
        const oBox = document.querySelector('.box');
 
        
        // ES6 構造函數 通過構造函數生成實例化對象
        const obj = new CreateTabObj(oBox, arr1);
        // 調用動態生成函數
        obj.setPage();
        // 調用點擊事件函數,參數為事件類型
        obj.setEvent("click");
 
    </script>
 
</body>
 
</html>

外鏈構造函數代碼:

// 在外部文件中定義構造函數
class CreateTabObj{
    // 構造器 定義屬性和屬性值
    // element  創建生成選項卡的標簽對象
    // msgArr   生成選項開內容的數組
    constructor( element , msgArr ){
        this.ele = element ;
        this.arr = msgArr ;
 
        // 定義屬性 存儲 面向過程中 需要的全局變量
        this.oUlLis;
        this.oOlLis;
    }
 
    // 構造器外定義函數方法
 
    // 函數1 動態生成頁面
    setPage(){
        // 創建固定的標簽節點 ul ol 
        const oUl = document.createElement('ul');
        const oOl = document.createElement('ol');
 
        // 定義字符串 存儲動態渲染生成的ul>li ol>li
        let ulLiStr = '';
        let olLiStr = '';
 
        // 循環遍歷數組 根據數組中的內容動態渲染生成li標簽
        
        // 之前是 直接調用 變量 arr1 中 存儲的數據 
        // 現在是 調用 實例化對象中arr屬性存儲的數據
        // arr1 ---> this.arr
        this.arr.forEach( function(item,key){
            // item 是 數組單元存儲的數據 也就是 存儲數據的對象
            // key 是 數組單元的索引下標
 
            // 第一個ul>li 有 class,active樣式
            ulLiStr += key === 0 ? `<li name="ulLi" index="${key}" class="active">${item.ulLi}</li>` : `<li index="${key}" name="ulLi">${item.ulLi}</li>` ;
 
            // 第一個ol>li 有 class,active樣式
            olLiStr += key === 0 ? `<li class="active">${item.olLi}</li>` : `<li>${item.olLi}</li>` ;
        });
 
 
        // 將字符串寫入ul ol 標簽
        oUl.innerHTML = ulLiStr ;
        oOl.innerHTML = olLiStr ;
 
        // 將 ul ol 標簽 寫入 div標簽中
 
        // 標簽對象 ---> this.ele
        this.ele.appendChild( oUl );
        this.ele.appendChild( oOl );
 
        // 獲取所有的ul>li
        this.oUlLis = oUl.querySelectorAll('li');
 
        // 獲取所有的ol>li
        this.oOlLis = oOl.querySelectorAll('li');
    }
 
    // 函數2 添加事件
    // 設定參數 存儲事件類型 可以是 click 可以是 mouseover 默認值是 mouseover
    setEvent( event = 'mouseover' ){
        // class 構造函數中 this指向 默認是 對象 
        console.log( this);
 
        // 給 父級標簽 添加 事件 通過事件委托完成效果
 
        // 提前定義一個變量 存儲 原始this指向
        const _this = this ;
 
        // 事件綁定 中 this指向改變 
 
        this.ele.addEventListener( event , function(e){
            // 事件綁定中 this指向 默認是 事件源 
            // 不再是 對象 
            // 也就是在 事件綁定中 this.屬性 不能 正確調用對象中的數據 
 
            if( e.target.getAttribute('name') === 'ulLi' ){
 
                // 清除所有 ul>li 的 class,active
 
                
                _this.oUlLis.forEach( function(item , key) {
 
                    // 給 ul>li 清除 class,active
                    item.classList.remove('active');
                    // 給 索引下標相同的 ol>li 清除 class,active
                    _this.oOlLis[key].classList.remove('active');
                })
 
                // 給 點擊的 ul>li 添加 class,active
                e.target.classList.add('active');
 
                // 給 點擊的 ul>li 索引下標 相同的 ol>li 添加 class,active
                _this.oOlLis[ Number( e.target.getAttribute('index') ) ].classList.add('active');
 
            }
        })
    }
}

運行結果:

 到此這篇關於JavaScript實現選項卡功能(面向過程與面向對象)的文章就介紹到這瞭,更多相關JavaScript 選項卡內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: