JS練習代碼庫(不定期更新)

目錄

0.常用代碼
1.點擊屏幕更換背景顏色【開關燈】
2.列表隔行變色
3.輸出九九乘法表
4.任意數求和
5.數組去重(四種方法)
6.JS圖片庫【DOM編程藝術】
7.JS圖片庫改進版【DOM編程藝術】
8.1-100不能被3整除的數相加【遞歸】
9.1-10能被2整除的數相乘【遞歸】
10.給列表中標題下方第一行的內容加粗【DOM】
11.數組的冒泡排序
12.數組的快速排序
13.數組的插入排序
14.編寫位置改變動畫函數【DOM編程藝術】
15.DOM動畫實例【DOM編程藝術】
16.類數組轉爲數組
17.HTML創建視頻控件【DOM編程藝術】
18.把JSON格式的字符串轉換爲JSON格式的對象
19.【DOM方法擴展】children——作用:獲取某一個容器中所有的元素子節點(還可以篩選出指定標籤名)
20.【DOM方法擴展】getElementsByClass——作用:通過元素的樣式類名獲取一組元素集合(兼容所有瀏覽器)
21.【DOM方法擴展】獲取上一個哥哥元素節點(prev)、獲取下一個弟弟元素節點(next)、獲取所有的哥哥元素節點(prevAll)、獲取所有的弟弟元素節點(nextAll)、獲取相鄰的兩個元素節點(sibling)、獲取所有的兄弟元素節點(siblings)
22.【DOM方法擴展】獲取第一個元素子節點(firstChild)、獲取最後一個元素子節點(lastChild)
23.【DOM方法擴展】獲取當前元素索引(index)
24.【DOM方法擴展】prepend——作用:增加到某一個容器的開頭(與appendChild對應)
25.【DOM方法擴展】insertAfter——作用:增加到容器中某一個元素的後面(與insertBefore對應)
26.【DOM方法擴展】hasClass——作用:判斷是否存在某一個樣式類名
27.【DOM方法擴展】removeClass——作用:刪除樣式類名
28.【DOM方法擴展】addClass——作用:給元素增加樣式類名
29.【DOM方法擴展】getCss、setCss、setGroupCss獲取/設置/批量設置css
30.【DOM方法擴展】css
31.js中簡易選項卡的實現(3種方法實現樣式的封裝)

0.常用代碼

1.類數組轉爲數組:

ary = Array.prototype.slice.call(類數組);

2.刪除數組中的某一項:

ary.splice(i, 1);

3.判斷是否爲IE瀏覽器:

if(/MSIE (6|7|8)/i.test(navigator.userAgent))

4.正則,以多個空格開頭或以多個空格結尾:

var reg = /(^ +| +$)/g;

5.將字符串按照空格拆分成數組:

var str = "this is my book"
str.split(" ");  //["this", "is", "my", "book"]
1.點擊屏幕更換背景顏色【開關燈】

需求:點擊屏幕,更換整體的背景顏色
分析:通過改變 this.style.backgroundColor的值,並且運用switch-case語句來實現
完整代碼如下:

<!doctype html>
<html lang="lang">
<head>
    <meta charset="UTF-8">
    <title>JS中判斷的應用【開關燈】</title>
    <style type="text/css">
        html, body {
            margin: 0;
            padding: 0;
            cursor: pointer;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body id="body">
<script type="text/javascript">
    var oBody = document.getElementById("body");
    oBody.onclick = function () {
        var bgColor = this.style.backgroundColor;
        switch (bgColor) {
            case "black":
                this.style.backgroundColor = "green";
                break;
            case "green":
                this.style.backgroundColor = "#294738";
                break;
            default:
                this.style.backgroundColor = "black";
        }
    };
</script>
</body>
</html>
2.列表隔行變色

需求:實現列表的奇偶行變色,並且鼠標移入也變色(js實現)
樣式圖:
這裏寫圖片描述
完整代碼如下:

<!doctype html>
<html lang="lang">
<head>
    <meta charset="UTF-8">
    <title>JS中判斷的應用【開關燈】</title>
    <style type="text/css">
        html, body {
            margin: 0;
            padding: 0;
            font-size: 15px;
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }

        ul {
            list-style: none;
            border: 1px solid #5bc0de;
            width: 600px;
            margin: 0 auto;
            padding: 0px;
        }

        li {
            padding: 10px 30px;
            cursor: pointer;
        }

        .c1 { /*奇數行顏色*/
            background-color: #5bc0de;
        }

        .c2 { /*偶數顏色*/
            background-color: #f7e1b5;
        }

        .c3 { /*移入顏色*/
            background-color: #999;
        }
    </style>
</head>
<body>
<ul>
    <li>NBA-正互動播湖人VS掘金 歐文首秀9+4+3綠軍勝</li>
    <li>傳喬治明夏或考慮留俄城 | 沃爾缺陣奇才大勝廣州29分</li>
    <li>中網-彭帥苦戰168分鐘 2-1險勝羅傑斯挺進次輪</li>
    <li>彭帥笑稱簽名時被叫阿姨 | 新科美網冠軍再遇一輪遊</li>
    <li>熱身賽-斯科拉20分馬布裏8分 山西末節逆轉北控</li>
    <li>18:30視頻播WBA拳王爭霸賽 | 20時視頻直播WCA淘汰賽</li>
    <li>中超-恆大與英勁旅爭安胖 權健老總:德比絕沒放水</li>
    <li>裏皮休假期與AC米蘭高層接觸 成紅黑軍新帥候選</li>
</ul>
<script type="text/javascript">
    var oLi = document.getElementsByTagName("li");
    for (var i = 0; i < oLi.length; i++) {
        var oLis = oLi[i];
        i % 2 === 0 ? (oLis.className = "c1" , oLis.old = "c1") : (oLis.className = "c2", oLis.old = "c2");
        oLis.onmouseover = function () {
            this.className = "c3";
        };
        oLis.onmouseout = function () {
            this.className = this.old;
        };
    }
</script>
</body>
</html>

也可以用閉包來實現:

<script type="text/javascript">
    var oLi = document.getElementsByTagName("li");
    for (var i = 0; i < oLi.length; i++) {
        ~function (i) {
            var oLis = oLi[i];
            i % 2 === 0 ? (oLis.className = "c1" , oLis.old = "c1") : (oLis.className = "c2", oLis.old = "c2");
            oLis.onmouseover = function () {
                oLi[i].className = "c3";
            };
            oLis.onmouseout = function () {
                oLi[i].className = oLi[i].old;
            };
        }(i);
    }
</script>
3.輸出九九乘法表

樣式:
這裏寫圖片描述
完整代碼如下:

<!doctype html>
<html lang="lang">
<head>
    <meta charset="UTF-8">
    <title>九九乘法表</title>
    <style type="text/css">
        table {
            margin: 0 auto;
        }

        tr {
            border: 1px solid rgb(230, 189, 189);
        }

        td, tr {
            padding: 5px 10px;
            font-size: 14px;
            color: rgb(177, 106, 104);
        }

        table tr:nth-child(odd) {
            background: rgb(238, 211, 210)
        }

        table tr:nth-child(even) {
            background: #FFF
        }
    </style>
</head>
<body>
<script type="text/javascript">
    document.write("<table>");
    var str = "";
    for (var i = 1; i <= 9; i++) {
        document.write("<tr>");
        for (var j = 1; j <= i; j++) {
            str += "<td>" + j + "*" + i + "=" + i * j + "</td>";
        }
        document.write(str);
        document.write("</tr>");
        str = "";
    }
    document.write("</table>");
</script>
</body>
</html>
4.任意數求和

需求:編寫一個函數sum,調用時無論傳遞多少個參數都能實現求和
js代碼如下:

<script type="text/javascript">
    function sum() {
        var _sum = 0;
        for (var i = 0; i < arguments.length; i++) {
            var num = Number(arguments[i]);
            if (!isNaN(num)) {
                _sum += num;
            }
        }
        return _sum;
    }
    console.log(sum(45, 66, "u", 77, 45)); //233
</script>
5.數組去重
方法一:遍歷數組法

方法分析:新建一個空數組。遍歷傳入數組的每一項,如果在新建的數組中找到了傳入數組的那一項,說明重複,如果找不到,就把當前項傳入到新建的數組中。最後返回新建的數組即可。
代碼如下:

function unique(arr) {
    var ary = [];
    for (var i = 0; i < arr.length; i++) {
        if (ary.indexOf(arr[i]) === -1) {
            ary.push(arr[i]);
        }
    }
    return ary;
}
方法二:對象鍵值對法

方法分析:創建一個空數組和一個空對象。遍歷傳入的數組,如果對象中沒有,就把遍歷的值當做屬性,對應的值爲1傳入對象中,同時把該值push到數組中。
代碼如下:

function unique(arr) {
    var ary = [];
    var obj = {};
    for (var i = 0; i < arr.length; i++) {
        if (!obj[arr[i]]) {
            ary.push(arr[i]);
            obj[arr[i]] = 1;
        }
    }
    return ary;
}
方法三:數組下標判斷法

方法分析:利用indexOf在查找時只能找到第一個匹配位置的值的特點。如果傳入的數組中的位置不等於循環的i,則說明該數是重複的。
代碼如下:

function unique(arr) {
    var ary = [];
    for (var i = 0; i < arr.length; i++) {
        if (arr.indexOf(arr[i]) === i) {
            ary.push(arr[i]);
        }
    }
    return ary;
}
方法四:排序後相鄰去除法

方法分析:對數組進行排序,然後比較相鄰的數字是否相等。不過該方法會將原數組進行排序。
代碼如下:

function unique(arr) {
    var ary = [];
    arr.sort(function (a, b) {
        return a - b;
    });
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] !== arr[i + 1]) {
            ary.push(arr[i]);
        }
    }
    return ary;
}
6.JS圖片庫【DOM編程藝術】

需求:點擊列表中的鏈接下方會出現圖片,並且頁面不跳轉,同時在圖片下方顯示圖片說明
樣式:
這裏寫圖片描述
步驟:

  1. 構建基本佈局
  2. 增加佔位符圖片
  3. 創建showPic函數,用來改變img標籤的src屬性
  4. 在a標籤上增加點擊事件,並防止跳轉
  5. 增加p標籤作爲圖片說明文字
  6. 綁定文字

完整代碼如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>6.JS圖片庫【DOM編程藝術】</title>
    <style type="text/css">
        #img {
            margin-top: 30px;
            width: 200px;
            height: 112px;
            background-color: #eee;
            text-align: center;
            clear: both;
        }

        #placeholder {
            vertical-align: middle;
        }

        span {
            display: inline-block;
            height: 100%;
            vertical-align: middle;
        }

        li {
            float: left;
            list-style: none;
            padding: 10px;
        }

        a {
            text-decoration: none;
        }
    </style>
</head>
<body>
<h1>JS圖片庫</h1>
<ul>
    <li><a href="img/1.jpg" title="flowers" onclick="showPic(this);return false;">flowers</a></li>
    <li><a href="img/2.jpg" title="desert" onclick="showPic(this);return false;">desert</a></li>
    <li><a href="img/3.jpg" title="city" onclick="showPic(this);return false;">city</a></li>
    <li><a href="img/4.jpg" title="sea" onclick="showPic(this);return false;">sea</a></li>
    <li><a href="img/5.jpg" title="bright" onclick="showPic(this);return false;">bright</a></li>
    <div id="img"><img id="placeholder" src="img/default.gif" alt="placeholder"/><span></span></div>
    <p id="text">圖片的描述</p>
</ul>
<script type="text/javascript">
    //改變img的src屬性:
    function showPic(whichPic) { //whichpic是一個元素節點
        var source = whichPic.getAttribute("href");
        document.getElementById("placeholder").setAttribute("src", source);
        document.getElementById("text").firstChild.nodeValue = whichPic.getAttribute("title");
    }
</script>
</body>
</html>
7.JS圖片庫改進版【DOM編程藝術】

改進方面有如下幾點:

  1. 將JavaScript代碼,即onclick事件分離
  2. 如果沒有佔位符,則圖片不能加載,所以最後的return false;應該由showPic函數來決定,即如果沒有的話,則正常跳轉頁面來顯示圖片
  3. 鏈接可以轉爲縮略圖

注意:按照實際情況來進行優化
效果圖:
這裏寫圖片描述
完整代碼如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>6.JS圖片庫【DOM編程藝術】</title>
    <style type="text/css">
        #box {
            margin-top: 30px;
            width: 200px;
            height: 112px;
            background-color: #eee;
            text-align: center;
            clear: both;
        }

        #placeholder {
            vertical-align: middle;
        }

        span {
            display: inline-block;
            height: 100%;
            vertical-align: middle;
        }

        li {
            float: left;
            list-style: none;
        }

        a {
            text-decoration: none;
        }

        a img {
            width: 100px;
            margin: 0 10px 20px 0;

        }
    </style>
</head>
<body>
<h1>JS圖片庫</h1>
<ul id="imagegallery">
    <li>
        <a href="img/1.jpg" title="flowers">
            <img src="img/1.jpg" alt="flowers"/>
        </a>
    </li>
    <li>
        <a href="img/2.jpg" title="desert">
            <img src="img/2.jpg" alt="desert"/>
        </a>
    </li>
    <li>
        <a href="img/3.jpg" title="city">
            <img src="img/3.jpg" alt="city"/>
        </a>
    </li>
    <li>
        <a href="img/4.jpg" title="sea">
            <img src="img/4.jpg" alt="sea"/>
        </a>
    </li>
    <li>
        <a href="img/5.jpg" title="bright">
            <img src="img/5.jpg" alt="bright"/>
        </a>
    </li>
    <div id="box"><img id="placeholder" src="img/default.gif" alt="placeholder"/><span></span></div>
    <p id="text">圖片的描述</p>
</ul>
<script type="text/javascript">
    //改變img的src屬性:
    function showPic(whichPic) { //whichpic是一個元素節點
        if (!document.getElementById("placeholder")) return false;
        var source = whichPic.getAttribute("href");
        document.getElementById("placeholder").setAttribute("src", source);
        if (document.getElementById("text")) {
            document.getElementById("text").firstChild.nodeValue = whichPic.getAttribute("title");
        }
        return true;
    }
    function prepareGallery() {
        if (!document.getElementsByTagName) return false;
        if (!document.getElementById) return false;
        if (!document.getElementById("imagegallery")) return false;
        var oLi = document.getElementsByTagName("a");
        for (var i = 0; i < oLi.length; i++) {
            oLi[i].onclick = function () {
                showPic(this);
                return !showPic(this);
            }
        }
    }
    window.onload = prepareGallery;
</script>
</body>
</html>
8.1-100不能被3整除的數相加【遞歸】

代碼如下:

function sum(n) {
    if (n === 0) {
        return 0;
    }
    if (n % 3 === 0) {
        return sum(n - 1);
    }
    return n + sum(n - 1);
}
console.log(sum(100));
9.1-10能被2整除的數相乘【遞歸】

代碼如下:

function sum(n) {
    if (n === 1) {
        return 1;
    }
    if (n % 2 === 0) {
        return sum(n - 1);
    }
    return n * sum(n - 1);
}
console.log(sum(10));
10.給列表中標題下方第一行的內容加粗【DOM】

原網頁效果如圖:

對應HTML代碼:

<h1>軍事新聞</h1>
<li>轟-20近期密集露面?美國披露中國戰略計劃 中美戰略平衡將被打破</li>
<li>日本又背後搞事!這次竟盯上了中國剛列裝的殲20</li>
<li>美友軍又擊落一架俄武裝直升機,專家稱俄敘聯軍這次輕敵代價太大</li>
<li>又一黑科技在中國成爲現實,即將運用到軍事上</li>
<h1>體育新聞</h1>
<li>周琦8+2火箭狂勝上海 書豪16分籃網勝</li>
<li>世預賽-明2:45播西班牙 阿根廷0-0跌第6</li>
<li>經紀人證實安帥或赴中國 權健闢謠將換帥</li>
<li>曝皮克夏奇拉分手 皇馬挖凱恩熱刺拒談判</li>
<h1>娛樂新聞</h1>
<li>定了!《戰狼2》競爭本屆奧斯卡“最佳外語片”</li>
<li>吳綺莉發文祝福出櫃女兒:不管怎樣永遠愛你</li>
<li>與毛曉彤分手因劈腿?曝陳翔出軌孫驍驍閨蜜</li>
<li>教子有方!張柏芝從小就教育兒子樂於助人</li>

要給列表中標題下方第一行的內容加粗,加粗後效果圖:


js代碼如下:

var oH1 = document.getElementsByTagName("h1");
function h1_nextNode(node) {
    if (node.nodeType === 1) {
        return node;
    } else {
        return h1_nextNode(node.nextSibling);
    }
}
for (var i = 0; i < oH1.length; i++) {
    var oLi = h1_nextNode(oH1[i].nextSibling);
    oLi.style.fontWeight = "bold";
}
11.數組的冒泡排序

算法分析:
冒泡排序的基本思想是每次比較兩個相鄰的元素,如果順序錯誤就把他們交換過來
兩次循環,外面的循環表示需要循環多少輪,裏面的循環表示每一輪中需要比較的次數。外層循環需要循環長度減一次,內層循環次數參考外層,是長度減去外層循環的次數。
代碼如下:

function bubbleSort(arr) {
    for (var i = 0; i < arr.length - 1; i++) {
        for (var j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                arr[j] += arr[j + 1];
                arr[j + 1] = arr[j] - arr[j + 1];
                arr[j] -= arr[j + 1];
            }
        }
    }
    return arr;
}
12.數組的快速排序

算法分析:
在數組中找一個基準點(一般爲數組的中間項),用基準點與數組中其他項進行比較。重複上面的步驟,直到每邊只有一個時停止。
代碼如下:

function quickSort(arr) {
    if (arr.length <= 1) return arr;
    var pointIndex = Math.floor(arr.length / 2); //找到基準點索引
    var pointValue = arr.splice(pointIndex, 1)[0]; //刪除基準點,並獲得該值
    var left = [];
    var right = [];
    for (var i = 0; i < arr.length; i++) {
        arr[i] < pointValue ? left.push(arr[i]) : right.push(arr[i]);
    }
    return quickSort(left).concat([pointValue], quickSort(right));
}
13.數組的插入排序

算法分析:
首先將數組第1個數看成是一個有序序列。將數組的第2個數按照關鍵字大小插入到這個有序序列中,插入後得到了一包含兩個數的有序序列。接下來再重複上面的步驟將第3,第4……第n-1個數分別插入到該有序序列中,最終得到一個包含n個數的有序序列。
代碼如下:

function insertSort(arr) {
    var newArr = [];
    newArr.push(arr[0]); //把第一項放進空數組中
    for (var i = 1; i < arr.length; i++) {
        var cur = arr[i]; //從第二項開始遍歷
        for (var j = newArr.length - 1; j >= 0;) { //循環新建的數組
            if (cur < newArr[j]) { //如果數組中的值比新建數組中的值小,就跟新建數組中的下一項比較
                j--;
                if (j === -1) {
                    newArr.unshift(cur); //把該值加入到數組開頭
                }
            } else {
                newArr.splice(j + 1, 0, cur); //把cur加在索引是j+1數字的前面
                j = -1; //退出循環,或者break;
            }
        }
    }
    return newArr;
}
14.編寫位置改變動畫函數【DOM編程藝術】

moveElement函數傳入元素id,位置及時間,可產生動畫效果
positionMessage函數來設置元素初始位置(如果原來有可忽略)
addLoadEvent函數用來執行
代碼如下

/* 參數說明:
 * elementID:打算移動元素的ID,
 * final_x:該元素的目的地的“左”位置,
 * final_y:該元素的目的地的“上”位置,
 * interval:兩次移動之間的停頓時間
 */
 function moveElement(elementID, final_x, final_y, interval) {
    var ele = document.getElementById(elementID);
    var xpos = parseInt(ele.style.left);
    var ypos = parseInt(ele.style.top);
    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x) xpos++;
    if (xpos > final_x) xpos--;
    if (ypos < final_y) ypos++;
    if (ypos > final_y) ypos--;
    ele.style.left = xpos + "px";
    ele.style.top = ypos + "px";
    movement = setTimeout(function () {
        moveElement(elementID, final_x, final_y, interval);
    }, interval);
}

function positionMessage() {
    var ele = document.getElementById("p");
    ele.style.position = "absolute";
    ele.style.left = "10px";
    ele.style.top = "20px";
    moveElement("p", 200, 200, 1);
}
addLoadEvent(positionMessage);

function addLoadEvent(f) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = f;
    } else {
        window.onload = function () {
            oldonload();
            f();
        }
    }
}
15.DOM動畫實例【DOM編程藝術】

有如下頁面:
這裏寫圖片描述
代碼如下:

<h1>Web Design</h1>
<p>These are the things you should know.</p>
<ol id="linklist">
    <li>
        <a href="structure.html">Structure</a>
    </li>
    <li>
        <a href="presentation.html">Presentation</a>
    </li>
    <li>
        <a href="behavior.html">Behavior</a>
    </li>
</ol>

在列表的下面插入一張縮略圖圖片:
這裏寫圖片描述
效果是鼠標在三個列表鏈接上滑動時,圖片也跟着運動
首先插入圖片:

<div id="slideshow">
    <img src="img/topics.gif" alt="building blocks of web design" id="preview"/>
</div>

效果如下:
這裏寫圖片描述

圖片是400*100的,然而只想顯示其中100*100的部分,需要用到CSS來處理。

#slideshow {
    width: 100px;
    height: 100px;
    position: relative;
    overflow: hidden;
}

此時只顯示了第一張圖片。接下來通過DOM來實現左右移動。
可以使用上面寫好的moveElement函數。
首先創建一個 prepareSlideshow函數來設定圖片的樣式併爲mouseover事件添加動畫,代碼如下:

function prepareSlideshow() {
    //設定圖片的位置
    var preview = document.getElementById("preview");
    preview.style.position = "absolute";
    preview.style.left = "0px";
    preview.style.top = "0px";

    //獲得列表中的鏈接
    var list = document.getElementsByTagName("a");

    //爲mouseover事件添加動畫
    list[0].onmouseover = function () {
        moveElement("preview", -100, 0, 10);
    };
    list[1].onmouseover = function () {
        moveElement("preview", -200, 0, 10);
    };
    list[2].onmouseover = function () {
        moveElement("preview", -300, 0, 10);
    };
}

此時,由於變量作用域的問題,當鼠標在鏈接之間快速移動的時候,因爲movement是全局作用域,不管moveElement函數是否執行完,都會進行下一項操作,此時moveElement函數會試圖把圖片拉向兩個方向,甚至會出現滯後停止的情況,爲了消除該影響,可以使用自定義屬性的方式來解決,解決後的moveElement函數代碼如下:

function moveElement(elementID, final_x, final_y, interval) {
    var ele = document.getElementById(elementID);
    //改進的代碼:
    if (ele.movement) {
        clearTimeout(ele.movement);
    }
    var xpos = parseInt(ele.style.left);
    var ypos = parseInt(ele.style.top);
    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x) xpos++;
    if (xpos > final_x) xpos--;
    if (ypos < final_y) ypos++;
    if (ypos > final_y) ypos--;
    ele.style.left = xpos + "px";
    ele.style.top = ypos + "px";
    //改進的代碼:
    ele.movement = setTimeout(function () {
        moveElement(elementID, final_x, final_y, interval);
    }, interval);
}

該元素在moveElement執行的時候會獲得一個movement屬性,但是如果在開始執行的時候就有movement屬性的話就說明上一次已經執行過動畫,用setTimeOut進行復位。
此時moveElement在移動時,每次只移動一個像素,移動較慢。爲了加快移動速度,可以進行如下改進:當元素距離其目的地較遠的時候,移動步數較大;較近時,移動步數較小。
改進後代碼如下:

function moveElement(elementID, final_x, final_y, interval) {
    var ele = document.getElementById(elementID);
    if (ele.movement) {
        clearTimeout(ele.movement);
    }
    var xpos = parseInt(ele.style.left);
    var ypos = parseInt(ele.style.top);
    var dist = 0;
    if (xpos === final_x && ypos === final_y) return true;
    if (xpos < final_x) {
        dist = Math.ceil((final_x - xpos) / 10);
        xpos += dist;
    }
    if (xpos > final_x) {
        dist = Math.ceil((xpos - final_x) / 10);
        xpos -= dist;
    }
    if (ypos < final_y) {
        dist = Math.ceil((final_y - ypos) / 10);
        ypos += dist;
    }
    if (ypos > final_y) {
        dist = Math.ceil((ypos - final_y) / 10);
        ypos -= dist;
    }
    ele.style.left = xpos + "px";
    ele.style.top = ypos + "px";
    ele.movement = setTimeout(function () {
        moveElement(elementID, final_x, final_y, interval);
    }, interval);
}

改進moveElement函數:如果傳入id對應元素的位置沒有被設置,那麼函數會出錯,爲了避免該錯誤,可以加入以下代碼:

if (!ele.style.left) {
    ele.style.left = "0px";
}
if (!ele.style.top) {
    ele.style.top = "0px";
}

該案例的完整代碼如下:(可以增加瀏覽器兼容的安全判斷)

<!doctype html>
<html lang="lang">
<head>
    <meta charset="UTF-8">
    <title>Explaining the Document Object Model</title>
    <style type="text/css">
        #slideshow {
            width: 100px;
            height: 100px;
            position: relative;
            overflow: hidden;
        }
    </style>
</head>
<body>
<h1>Web Design</h1>
<p>These are the things you should know.</p>
<ol id="linklist">
    <li>
        <a href="structure.html">Structure</a>
    </li>
    <li>
        <a href="presentation.html">Presentation</a>
    </li>
    <li>
        <a href="behavior.html">Behavior</a>
    </li>
</ol>
<div id="slideshow">
    <img id="preview" src="img/topics.gif" alt="building blocks of web design"/>
</div>
<script type="text/javascript">
    /* 參數說明:
     * elementID:打算移動元素的ID,
     * final_x:該元素的目的地的“左”位置,
     * final_y:該元素的目的地的“上”位置,
     * interval:兩次移動之間的停頓時間
     */
    function moveElement(elementID, final_x, final_y, interval) {
        var ele = document.getElementById(elementID);
        if (ele.movement) {
            clearTimeout(ele.movement);
        }
        if (!ele.style.left) {
            ele.style.left = "0px";
        }
        if (!ele.style.top) {
            ele.style.top = "0px";
        }
        var xpos = parseInt(ele.style.left);
        var ypos = parseInt(ele.style.top);
        var dist = 0;
        if (xpos === final_x && ypos === final_y) return true;
        if (xpos < final_x) {
            dist = Math.ceil((final_x - xpos) / 10);
            xpos += dist;
        }
        if (xpos > final_x) {
            dist = Math.ceil((xpos - final_x) / 10);
            xpos -= dist;
        }
        if (ypos < final_y) {
            dist = Math.ceil((final_y - ypos) / 10);
            ypos += dist;
        }
        if (ypos > final_y) {
            dist = Math.ceil((ypos - final_y) / 10);
            ypos -= dist;
        }
        ele.style.left = xpos + "px";
        ele.style.top = ypos + "px";
        ele.movement = setTimeout(function () {
            moveElement(elementID, final_x, final_y, interval);
        }, interval);
    }

    function prepareSlideshow() {
        //設定圖片的位置
        var preview = document.getElementById("preview");
        preview.style.position = "absolute";
        preview.style.left = "0px";
        preview.style.top = "0px";
        //獲得列表中的鏈接
        var list = document.getElementsByTagName("a");
        //爲mouseover事件添加動畫
        list[0].onmouseover = function () {
            moveElement("preview", -100, 0, 10);
        };
        list[1].onmouseover = function () {
            moveElement("preview", -200, 0, 10);
        };
        list[2].onmouseover = function () {
            moveElement("preview", -300, 0, 10);
        };
    }

    addLoadEvent(prepareSlideshow);
    function addLoadEvent(f) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = f;
        } else {
            window.onload = function () {
                oldonload();
                f();
            }
        }
    }
</script>
</body>
</html>
16.類數組轉爲數組
function listToArray(likeAry) {
    var ary = [];
    try {
        ary = Array.prototype.slice.call(likeAry);
    } catch (e) {
        for (var i = 0; i < likeAry.length; i++) {
            ary[ary.length] = likeAry[i];
        }
    }
    return ary;
}
17.HTML創建視頻控件【DOM編程藝術】

效果圖:
這裏寫圖片描述

HTML代碼:

<!doctype html>
<html lang="lang">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="HTML5.css"/>

</head>
<body>
<div class="video-wrapper">
    <video id="movie" controls>
        <source src="video/oceans-clip.mp4"/>
        <source src="video/oceans-clip.webm" type='video/webm,codecs="vp8,vorbis"'/>
        <source src="video/oceans-clip.ogv" type='video/ogg; codecs="theora, vorbis"'/>
        <p>Download movie as
            <a href="video/oceans-clip.mp4">mp4</a>
            <a href="video/oceans-clip.webm">webm</a>
            <a href="video/oceans-clip.ogv">ogv</a>
        </p>
    </video>
</div>
<script src="HTML5.js"></script>
</body>
</html>

JavaScript代碼:

//對video元素應用addControls函數
function createVideoControls() {
    var vids = document.getElementsByTagName("video");
    for (var i = 0; i < vids.length; i++) {
        addControls(vids[i]);
    }
}

//刪除原來的controls屬性,添加播放暫停功能
function addControls(vid) {
    vid.removeAttribute("controls"); //刪除原來的controls屬性

    //設置視頻的寬高尺寸
    vid.height = vid.videoHeight;
    vid.width = vid.videoWidth;
    vid.parentNode.style.height = vid.videoHeight + "px";
    vid.parentNode.style.width = vid.videoWidth + "px";

    //新建一個div元素,class屬性是controls
    var controls = document.createElement("div");
    controls.setAttribute("class", "controls");

    //新建一個按鈕元素,title屬性爲play,按鈕的內容是►
    var play = document.createElement("button");
    play.setAttribute("title", "play");
    play.innerHTML = "&#x25BA;";

    //把按鈕放在div中
    //在video元素的父元素後添加div元素,位於video元素之前
    controls.appendChild(play);
    vid.parentNode.insertBefore(controls, vid);

    //給按鈕添加點擊事件
    play.onclick = function () {
        //如果播放結束,視頻中的當前播放位置爲0
        if (vid.ended) {
            vid.currentTime = 0;
        }
        //如果點擊暫停按鈕,開始播放視頻,否則暫停
        if (vid.paused) {
            vid.play();
        } else {
            vid.pause();
        }
    };

    vid.addEventListener("play", function () {
        play.innerHTML = "&#2590;&#2590;";
        play.setAttribute("paused", true);
    }, false);

    vid.addEventListener("pause", function () {
        play.removeAttribute("paused");
        play.innerHTML = "&#x25BA;";
    }, false);

    vid.addEventListener("ended", function () {
        vid.pause();
    }, false);
}

window.onload = function () {
    createVideoControls();
}
18.把JSON格式的字符串轉換爲JSON格式的對象

JSON.parse:把JSON格式的字符串轉換爲JSON格式的對象
JSON.stringify:把JSON格式的對象轉換爲JSON格式的字符串
但是,在IE6和7中,window下沒有JSON對象,parse和stringify都不存在
故,兼容模式代碼:

function json(jsonStr) {
    return 'JSON' in window ? JSON.parse(jsonStr) : eval("(" + jsonStr + ")");
}
19.【DOM方法擴展】children——作用:獲取某一個容器中所有的元素子節點(還可以篩選出指定標籤名)

children方法在非標準瀏覽器下不兼容
算法分析:首先獲取所有的子節點(childNode),在所有的子節點中,把元素節點過濾出來,即nodeType===1。如果多傳一個標籤名,進行二次篩選,獲取指定標籤名的集合。代碼如下:

//curEle獲取到的元素,tagName要篩選的標籤名
function children(curEle, tagName) {
    var ary = [];
    if (/MSIE (6|7|8)/i.test(navigator.userAgent)) {
        var nodeList = curEle.childNodes;
        for (var i = 0; i < nodeList.length; i++) {
            nodeList[i].nodeType === 1 ? ary[ary.length] = nodeList[i] : null;
        }
    } else {
        ary = Array.prototype.slice.call(curEle.children);
    }
    if (typeof tagName === "string") {
        for (var j = 0; j < ary.length; j++) {
            if (ary[j].nodeName.toLowerCase() !== tagName.toLowerCase()) {
                ary.splice(j, 1);
                j--;
            }
        }
    }
    return ary;
}
20.【DOM方法擴展】getElementsByClass——作用:通過元素的樣式類名獲取一組元素集合(兼容所有瀏覽器)

getElementsByClassName()原方法:寫一個樣式類名的話,只要包含這個樣式類名就可以;寫兩個的話,只要同時包含這兩個就可以,但和樣式的順序以及中間有多少個空格是沒有關係的;如果不寫,結果是一個空的集合

思路圖解:
這裏寫圖片描述

var flag = "getComputedStyle" in window;
//className:要獲取的類名
//context:上下文,不寫默認爲document
function getElementsByClass(className, context) {
    context = context || document;
    if (flag) {
        return Array.prototype.slice.call(context.getElementsByClassName(className));
    }
    var ary = [],
        classNameAry = className.replace(/(^ +| +$)/g).split(/ +/g); //classNameAry是多個class名字的數組
    var nodeList = context.getElementsByTagName("*"); //nodeList是上下文中所有標籤的集合
    var isOk = true;
    for (var i = 0; i < nodeList.length; i++) {
        for (var j = 0; j < classNameAry.length; j++) {
            var reg = new RegExp("(^| +)" + classNameAry[j] + "( +|$)");
            if (!reg.test(nodeList[i].className)) {
                isOk = false;
                break;
            }
        }
        if (isOk) {
            ary[ary.length] = nodeList[i];
        }
    }
    return ary;
}
21.【DOM方法擴展】獲取上一個哥哥元素節點(prev)、獲取下一個弟弟元素節點(next)、獲取所有的哥哥元素節點(prevAll)、獲取所有的弟弟元素節點(nextAll)、獲取相鄰的兩個元素節點(sibling)、獲取所有的兄弟元素節點(siblings)

獲取上一個哥哥元素節點(prev)

prev算法分析:首先獲取當前元素的上一個哥哥節點,判斷是否爲元素節點,不是的話基於當前的繼續找上面的哥哥節點,一直找到哥哥元素節點爲止,如果沒有哥哥節點,返回null。代碼如下:

var flag = "getComputedStyle" in window;
//curEle:要查找的元素
function prev(curEle) {
    if (flag) {
        return curEle.previousElementSibling;
    }
    var pre = curEle.previousSibling;
    while (pre && pre.nodeType !== 1) {
        pre = pre.previousSibling;
    }
    return pre;
}

獲取下一個弟弟元素節點(next)

var flag = "getComputedStyle" in window;
//curEle:要查找的元素
function next(curEle) {
    if (flag) {
        return curEle.nextElementSibling;
    }
    var nex = curEle.nextSibling;
    while (nex && nex.nodeType !== 1) {
        nex = nex.nextSibling;
    }
    return nex;
}

獲取所有的哥哥元素節點(prevAll)

//curEle:要查找的元素
function prevAll(curEle) {
    var pre = prev(curEle);
    var ary = [];
    while (pre) {
        ary.unshift(pre);
        pre = prev(pre);
    }
    return ary;
}

獲取所有的弟弟元素節點(nextAll)

//curEle:要查找的元素
function nextAll(curEle) {
    var nex = next(curEle);
    var ary = [];
    while (nex) {
        ary.push(nex);
        nex = next(nex);
    }
    return ary;
}

獲取相鄰的兩個元素節點(sibling)

function sibling(curEle) {
    var pre = this.prev(curEle);
    var nex = this.next(curEle);
    var ary = [];
    pre ? ary.push(pre) : null;
    nex ? ary.push(nex) : null;
    return ary;
}

獲取所有的兄弟元素節點(siblings)

function siblings(curEle) {
    return this.prevAll(curEle).concat(this.nextAll(curEle));
}
22.【DOM方法擴展】獲取第一個元素子節點(firstChild)、獲取最後一個元素子節點(lastChild)

獲取第一個元素子節點(firstChild)

function firstChild(curEle) {
    var chs = this.children(curEle);
    return chs.length > 0 ? chs[0] : null;
}

獲取最後一個元素子節點(lastChild)

function lastChild(curEle) {
    var chs = this.children(curEle);
    return chs.length > 0 ? chs[chs.length-1] : null;
}
23.【DOM方法擴展】獲取當前元素索引(index)

有幾個哥哥索引就是幾,代碼如下:

function index(curEle) {
    return this.prevAll(curEle).length;
}
24.【DOM方法擴展】prepend——作用:增加到某一個容器的開頭(與appendChild對應)

算法分析:把新的元素添加到容器中第一個子元素節點的前面,如果一個元素子節點都沒有,就放在末尾即可

function prepend(newEle, container) {
    var fir = this.firstChild(container);
    if (fir) {
        container.insertBefore(newEle, fir);
        return;
    }
    container.appendChild(newEle);
}
25.【DOM方法擴展】insertAfter——作用:增加到容器中某一個元素的後面(與insertBefore對應)
function insertAfter(newEle, oldEle) {
    var nex = this.next(oldEle);
    if (nex) {
        oldEle.parentNode.insertBefore(newEle, nex);
        return;
    }
    oldEle.parentNode.appendChild(newEle);
}
26.【DOM方法擴展】hasClass——作用:判斷是否存在某一個樣式類名
//curEle:要查找的元素
//className:樣式名
function hasClass(curEle, className) {
    var reg = new RegExp("(^| +)" + className + "( +|$)");
    return reg.test(curEle.className);
}
27.【DOM方法擴展】removeClass——作用:刪除樣式類名
function removeClass(curEle, className) {
    var ary = className.replace(/(^ +| +$)/g,"").split(/ +/g);
    for (var i = 0; i < ary.length; i++) {
        var curName = ary[i];
        if (this.hasClass(curEle, curName)) {
            var reg = new RegExp("(^| +)" + curName + "( +|$)", "g");
            curEle.className = curEle.className.replace(reg, " ");
        }
    }
}
28.【DOM方法擴展】addClass——作用:給元素增加樣式類名
29.【DOM方法擴展】getCss、setCss、setGroupCss獲取/設置/批量設置css

getCss:獲取css
setCss:設置css
setGroupCss:批量設置css

30.【DOM方法擴展】getCss、setCss、setGroupCss獲取/設置/批量設置css
31.js中簡易選項卡的實現(3種方法實現樣式的封裝)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章