最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript跨瀏覽器獲取頁面中相同class節(jié)點(diǎn)的方法

 更新時(shí)間:2015年03月03日 09:24:52   作者:玉面小飛魚  
這篇文章主要介紹了JavaScript跨瀏覽器獲取頁面中相同class節(jié)點(diǎn)的方法,本文講解使用getELementsByClassName函數(shù)解決這個(gè)需求,并給了一個(gè)開源的getELementsByClassName函數(shù)實(shí)現(xiàn),功能更加強(qiáng)大,需要的朋友可以參考下

網(wǎng)頁開發(fā)時(shí),在很多時(shí)候我們需要操作相同類名的元素,即class相同的元素。昨天參加筆試,有一道相關(guān)的題目沒答上來:

JavaScript獲取頁面中class為test的節(jié)點(diǎn)

于是收集了一些相關(guān)的資料,在本文中列舉了兩種我覺得比較好的方法,不足之處,還望大家批評指正。如果大家有更好的方法,希望可以分享。

Solution1 Jeremy Keuth方案

Jeremy Keuth大叔在《JavaScript DOM 編程藝術(shù)》(第2版)(英文:DOM Scripting-Web Design with JavaScript and the Document Object Model)一書的第三章第四節(jié)中講到了getElementsByClass這個(gè)方法,并講到了如何在不支持該屬性的瀏覽器(IE6,IE7和IE8,讓我們鄙視他們)中應(yīng)用這一方法,摘錄在此,個(gè)別地方有修改。

HTML5 DOM中新增了一個(gè)方法讓我們通過class屬性中的類名來訪問元素,這就是:getELementsByClassName,由于方法比較新,某些的DOM實(shí)現(xiàn)里還沒有,因此在使用的時(shí)候要當(dāng)心。下面我們先來看一看這個(gè)方法能幫我們做什么,然后在討論怎么可靠的使用該方法。
與getELementsByTagName方法類似,getElementsByClassName也只接受一個(gè)參數(shù),就是類名:

復(fù)制代碼 代碼如下:

getElementsByClassName(class)

這個(gè)方法的返回值也與getElementsByTagName類似,都是一個(gè)具有相同類名的元素的數(shù)組,下面這行代碼返回的就是一個(gè)數(shù)組,其中包含類名為“sale”的所有元素:
復(fù)制代碼 代碼如下:

document.getElementsByClassName("sale")

使用這個(gè)方法還可以查找那些帶有多個(gè)類名的元素。要指定多個(gè)類名,只要在字符串參數(shù)中用空格分隔類名即可。例如,在<script>標(biāo)簽中添加下面這行代碼:
復(fù)制代碼 代碼如下:

alert(document.getElementsByClassName("sale important").length);

完整代碼

復(fù)制代碼 代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Shopping List</title>
</head>
<body>
    <h1>What to buy</h1>
    <p title="a gentle reminder">Don't forget to buy this stuff.</p>
    <ul id="purchase">
        <li>A thin of beans</li>
        <li class="sale">Cheese</li>
        <li class="sale important">Milk</li>
    </ul>
    <script>
         alert(document.getElementsByClassName("sale important").length);
    </script>
</body>
</html>

你會看到警告框中顯示1,表示只有一個(gè)元素匹配,因?yàn)橹挥幸粋€(gè)元素同時(shí)帶有”important”和”sale”類名。注意,即使在元素的class屬性中,類名的順序是”sale important”而非參數(shù)中指定的”important sale”,也會照樣匹配該元素。不僅類名的實(shí)際順序不重要,就算元素還帶有更多類名也沒有關(guān)系。與使用getELementsByTagName一樣,也可以組合使用getElementsByClassName和getElementById。如果你想知道在id為purchase的元素中有多少類名包含test的列表項(xiàng),可以先找到那個(gè)特定的對象,然后再調(diào)用getElementsByClassName:

復(fù)制代碼 代碼如下:

var shopping=document.getElementById("purchase");
var sales = shopping.getElementsByClassName("sale");

這樣,sales數(shù)組中包含的就只是位于”purchase”列表中的帶有”sales”類的元素,運(yùn)行下面這行代碼,就會看到sales數(shù)組包含兩項(xiàng):

復(fù)制代碼 代碼如下:

alert(sales.length);

這個(gè)getELementsByClassName方法非常有用,但只有較新的瀏覽器(Safari 3.1,Chorme,F(xiàn)irefox 3 and Opera 9.5以上)才支持它。為了彌補(bǔ)這一不足,DOM腳本程序員需要使用已有的DOM方法來實(shí)現(xiàn)自己的getElementsByClassName,有點(diǎn)像成人禮似的。而多數(shù)情況下,他們的實(shí)現(xiàn)過程都與下面這個(gè)getElementsByClassName大致相似,這個(gè)函數(shù)能適用于新老瀏覽器。

復(fù)制代碼 代碼如下:

function getElementsByClassName(node,classname){
    if(node.getElementsByClassName){
         return node.getElementsByClassName(classname);
    }else{
        var results = [];
        var elems = node.getElementsByTagName("*");
        for(var i=0;i<elems.length;i++){
            if(elems[i].className.indexOf(classname)!=-1){
                results[results.length]=elems[i];
            }
        }
    return results;
    }
}

這個(gè)getElementsByClassName函數(shù)接受兩個(gè)參數(shù)。第一個(gè)node表示DOM樹中的搜索起點(diǎn),第二個(gè)classname就是要搜索的類名了。如果傳入節(jié)點(diǎn)上已經(jīng)存在了適當(dāng)?shù)膅etElementsByClassName函數(shù),那么這個(gè)新函數(shù)就直接返回相應(yīng)的節(jié)點(diǎn)列表。如果getElementsByClassName函數(shù)不存在,這個(gè)新函數(shù)就會循環(huán)遍歷所有標(biāo)簽,查找?guī)в邢鄳?yīng)類名的元素。

這個(gè)方法的缺點(diǎn)是不適用于多個(gè)類名。

如果使用這個(gè)函數(shù)來模擬前面取得購物列表的操作,就可以這樣寫:

復(fù)制代碼 代碼如下:

var shopping=document.getElementById("purchase");
var sales = shopping.getElementsByClassName(shopping,"test");
console.log(sales);

因此,要解決文章開頭的那道題目,所用代碼如下:

復(fù)制代碼 代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Shopping List</title>
</head>
<body>
    <h1>What to buy</h1>
    <p title="a gentle reminder">Don't forget to buy this stuff.</p>
    <ul id="purchase">
        <li>A thin of beans</li>
        <li class="sale">Cheese</li>
        <li class="sale important">Milk</li>
    </ul>
<script>
    function getElementsByClassName(node,classname){
        if(node.getElementsByClassName){
            return node.getElementsByClassName(classname);
        }else{
            var results = [];
            var elems = node.getElementsByTagName("*");
            for(var i=0;i<elems.length;i++){
               if(elems[i].className.indexOf(classname)!=-1){
                   results[results.length]=elems[i];
               }
            }
            return results;
        }
    }
    var body = document.getElementsByTagName("body")[0];
    var sales= getElementsByClassName(body,"sales");
    console.log(sales);
</script>
</body>
</html>

Solution2 Robert Nyman方案

搜索匹配的DOM元素的方法還有很多,但真正高效的卻不多,Jeremy Keuth大叔的方法有一個(gè)缺點(diǎn)就是不能用于多個(gè)類名,2008年,Robert Nyman在文章 The Ultimate GetElementsByClassName, Anno 2008中提供了自己的解決方案。在2005年,Robert大叔就已經(jīng)給出了自己的getElementsByClassName的函數(shù),在2008年的時(shí)候,修改了部分代碼,添加了許多新的功能:

1.如果當(dāng)前瀏覽器支持getElementsByClassName函數(shù),則調(diào)用該原生函數(shù);
2.如果當(dāng)前瀏覽器支持則使用XPath;//小飛魚:一種瀏覽器內(nèi)置的定位XML文檔的強(qiáng)大方式,不過瀏覽器支持方面不統(tǒng)一
3.支持多個(gè)類名的搜索,不計(jì)先后順序;
4.返回真正的節(jié)點(diǎn)數(shù)組,而不是原生的一個(gè)nodelist。//小飛魚:原生的getElementsByClassName方法返回的是一個(gè)NodeList對象,它很像數(shù)組,有l(wèi)ength和數(shù)字索引屬性,但并不是數(shù)組,不能用pop,push等數(shù)組特有的方法,Robert提供的代碼中,將NodeList對象轉(zhuǎn)成了數(shù)組??梢詫odeList對象轉(zhuǎn)換成數(shù)組的方法:

復(fù)制代碼 代碼如下:

myList = Array.prototype.slice.call (myNodeList)

這是Robert大叔的方法,有些地方還不太明白,待我研究一下再來更新好了。

復(fù)制代碼 代碼如下:

/*
Developed by Robert Nyman, http://www.robertnyman.com
Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/
var getElementsByClassName = function (className, tag, elm){
    if (document.getElementsByClassName) {
        getElementsByClassName = function (className, tag, elm) {
            elm = elm || document;
            var elements = elm.getElementsByClassName(className),
                nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
                returnElements = [],
                current;
            for(var i=0, il=elements.length; i<il; i+=1){
                current = elements[i];
                if(!nodeName || nodeName.test(current.nodeName)) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        };
    }
    else if (document.evaluate) {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = "",
                xhtmlNamespace = "http://www.w3.org/1999/xhtml",
                namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
                returnElements = [],
                elements,
                node;
            for(var j=0, jl=classes.length; j<jl; j+=1){
                classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
            }
            try {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
            }
            catch (e) {
                elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
            }
            while ((node = elements.iterateNext())) {
                returnElements.push(node);
            }
            return returnElements;
        };
    }
    else {
        getElementsByClassName = function (className, tag, elm) {
            tag = tag || "*";
            elm = elm || document;
            var classes = className.split(" "),
                classesToCheck = [],
                elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
                current,
                returnElements = [],
                match;
            for(var k=0, kl=classes.length; k<kl; k+=1){
                classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
            }
            for(var l=0, ll=elements.length; l<ll; l+=1){
                current = elements[l];
                match = false;
                for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
                    match = classesToCheck[m].test(current.className);
                    if (!match) {
                        break;
                    }
                }
                if (match) {
                    returnElements.push(current);
                }
            }
            return returnElements;
        };
    }
    return getElementsByClassName(className, tag, elm);
};

相關(guān)文章

  • JavaScript中for循環(huán)的幾種寫法與效率總結(jié)

    JavaScript中for循環(huán)的幾種寫法與效率總結(jié)

    每個(gè)接觸JS的開發(fā)人員都不可避免的與for循環(huán)打交道,畢竟這是遍歷必不可少的工具之一。然而當(dāng)循環(huán)次數(shù)比較大時(shí),效率問題必須重視。下面這篇文章就主要介紹了JavaScript中幾種for循環(huán)的寫法與效率,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-02-02
  • 原生JS實(shí)現(xiàn)圖片無縫滾動方法(附帶封裝的運(yùn)動框架)

    原生JS實(shí)現(xiàn)圖片無縫滾動方法(附帶封裝的運(yùn)動框架)

    下面小編就為大家?guī)硪黄鶭S實(shí)現(xiàn)圖片無縫滾動方法(附帶封裝的運(yùn)動框架)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • hash特點(diǎn)、hashchange事件介紹及其常見應(yīng)用場景

    hash特點(diǎn)、hashchange事件介紹及其常見應(yīng)用場景

    淺析hash特點(diǎn)、hashchange事件介紹及其常見應(yīng)用場景(不同hash對應(yīng)不同事件處理、移動端大圖展示狀態(tài)后退頁面問題、原生輕應(yīng)用頭部后退問題、移動端自帶返回按鈕二次確認(rèn)問題),hashchange和popstate事件觸發(fā)條件
    2023-11-11
  • JavaScrip調(diào)試技巧之?dāng)帱c(diǎn)調(diào)試

    JavaScrip調(diào)試技巧之?dāng)帱c(diǎn)調(diào)試

    本篇文章給大家介紹javascript調(diào)試技巧之?dāng)帱c(diǎn)調(diào)試,主要介紹使用Firebug、debugger、debugger在程序中加入斷點(diǎn)調(diào)試等,但是這些調(diào)試技巧都不借助于瀏覽器之外的工具,其他瀏覽器主要是opera、safari、chrome和ie8,感興趣的小伙伴一起看看吧
    2015-10-10
  • js性能優(yōu)化 如何更快速加載你的JavaScript頁面

    js性能優(yōu)化 如何更快速加載你的JavaScript頁面

    JavaScript現(xiàn)在極其重要。一些網(wǎng)站使用JavaScript來增添魅力;如今的許多Web應(yīng)用程序依賴它;其中一些甚至是完全用JavaScript編寫而成的。我在本文中將指出一些重要的規(guī)則,介紹如何使用你的JavaScript、使用哪些工具以及你將從中得到什么好處
    2012-03-03
  • 微信小程序自定義tabBar組件開發(fā)詳解

    微信小程序自定義tabBar組件開發(fā)詳解

    這篇文章主要為大家詳細(xì)介紹了微信小程序自定義tabBar組件開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • js中的WebSocket使用及說明

    js中的WebSocket使用及說明

    這篇文章主要介紹了js中的WebSocket使用及說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 在線編輯器的實(shí)現(xiàn)原理(兼容IE和FireFox)

    在線編輯器的實(shí)現(xiàn)原理(兼容IE和FireFox)

    在線編輯器的實(shí)現(xiàn)原理(兼容IE和FireFox)...
    2007-03-03
  • 解決微信小程序云開發(fā)中獲取數(shù)據(jù)庫的內(nèi)容為空的方法

    解決微信小程序云開發(fā)中獲取數(shù)據(jù)庫的內(nèi)容為空的方法

    這篇文章主要介紹了解決微信小程序云開發(fā)中獲取數(shù)據(jù)庫的內(nèi)容為空的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-05-05
  • 原生JavaScript再網(wǎng)頁實(shí)現(xiàn)文本轉(zhuǎn)語音功能

    原生JavaScript再網(wǎng)頁實(shí)現(xiàn)文本轉(zhuǎn)語音功能

    這篇文章主要為大家詳細(xì)介紹了如何通過原生JavaScript再網(wǎng)頁實(shí)現(xiàn)文本轉(zhuǎn)語音功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2025-03-03

最新評論

法库县| 东光县| 方山县| 龙井市| 姜堰市| 义乌市| 南溪县| 江华| 策勒县| 剑阁县| 土默特右旗| 江华| 抚松县| 罗山县| 民丰县| 富蕴县| 清河县| 海晏县| 西畴县| 扶风县| 东莞市| 漯河市| 左权县| 吉安县| 鄂尔多斯市| 禹州市| 宜黄县| 塘沽区| 梁河县| 台山市| 景谷| 柘城县| 娄烦县| 朝阳市| 澄城县| 白城市| 射洪县| 扎赉特旗| 天全县| 宝坻区| 玉山县|