首頁 web前端 js教程 jquery中類別選擇器的功能如何實作實例詳解

jquery中類別選擇器的功能如何實作實例詳解

Jun 17, 2017 am 10:55 AM
jquery 功能 如何 實現 選擇器

一、类选择器的概念

类选择器,就是通过class属性获取节点。比如一个html结构中,有三个p标签都具有class=”red”的属性,那么类选择器返回的就是这三个p标签。

在jquery中,我们可以很方便的通过$(“.red”)这种方式按照类获取节点。但是在原生的javascript中,有getElementById(按照id属性获取元素)、getElementsByTagName(按照标签名获取元素)等方法,但是并没有类选择器相关方法。因此,编写原生js实现类选择器的方法非常关键。 

二、类选择器的实现

通过利用原生js编写类选择器,可以更深入的了解js中的DOM相关操作,下面我们就来看一个简单的类选择器是如何实现的:

function getElementsByClass(classnames){
  var classobj = newArray();
  var classint = 0;
  var tags =document.getElementsByTagName("*");
  for(var i in tags){
   if(tags[i].nodeType == 1){
     if(tags[i].getAttribute("class") == classnames){
       classobj[classint] = tags[i];
        classint++;
      }
    }
  }
  return classobj;
}
登入後複製

我们封装了一个getElementsByClass()方法,该方法的效果是:获取所有DOM节点,它们的class属性为选定值,并返回到一个数组中。该方法传递一个参数,即需要选择的class值。

该类选择器的实现方法,首先创建一个空的数组classobj,用来存放获取到的DOM节点。classint变量用来进行索引的表示,方便数组操作。我们利用getElementsByTagName(“*”)方法获取了这个页面上的所有DOM节点(*表示匹配所有)。

取出了所有DOM节点,我们就可以进行判断了。循环遍历取到的每一个节点,如果它的nodeType是1(元素节点),则利用getAttribute(“class”)方法获取节点的class属性值,并与传递进来的class参数进行比对,如果相同,说明是我们想要的节点,存入事先定义好的数组中。最后返回该数组即可。

三、原生js类选择器测试

下面我们来验证一下我们自己编写的类选择器是否正常工作,测试代码如下:

<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>无标题文档</title>
<scriptsrc="classtest.js"></script>
<script>
window.onload =function(){
   var a = getElementsByClass("atest");
  a[0].onmouseover = function(){
    alert("class!!");
  }
}
</script>
<style>
.atest{background:blue;width:200px;height:200px;margin:40px;color:white;}
.btest{background:green;width:200px;height:200px;margin:40px;color:white;}
</style>
</head>
<body>
<pclass="atest">atestAAA</p>
<pclass="btest">atestBBB</p>
</html>
登入後複製

该代码我们利用我们自己封装的方法进行了测试,获取class为atest的元素,鼠标滑过后会弹出对话框。

注意我们封装的这个方法返回的是一个数组,就如同jquery中的sibling()方法一样,需要加入索引才能选中元素。如果一个页面有多个选中元素,可以利用数组循环遍历进行相应操作。

封装了一个盒jquery使用方法相同的库,每次写都有新的想法,所有代码的注释已经写到行间的注释了

/**
 * Created by Jason on 2016/12/31.
 */
//jquery 的构造函数
function Jquery(arg){
    //用来存选出来的元素
    this.elemenets=[];
    switch(typeof arg){
        case &#39;function&#39; :
            domReady(arg);
            break;
        case &#39;string&#39; :
            this.elements = getEle(arg);
            break;
        case &#39;object&#39; :
            this.elements.push(arg);
            break;
    }
}
//DOM ready onload 如果参数是函数,则进行domReady操作
function domReady(fn){
    // FF chrome
    if(document.addEventListener){
        //jquery中已经省略false,false解决低版本火狐兼容性问题
        document.addEventListener(&#39;DOMContentLoaded&#39;,fn,false);
    }else{
        document.attachEvent(&#39;onreadystatechange&#39;,function(){
            if(document.readyState==&#39;complete&#39;){
                fn();
            }
        });
    }
}
function getByClass(oParent,sClass){
    //高级浏览器支持getElementsByClassName直接使用
    if(oParent.getElementsByClassName){
        return oParent.getElementsByClassName(sClass);
    }else{
        //不支持需要选中所有标签的类名来选取
        var res=[];
        var aAll=oParent.getElementsByTagName(&#39;*&#39;);
        for(var i=0;i<aAll.length;i++){
            //选中标签的全部类名是个str=&#39;btn on red&#39;=aAll[i].className   使用正则  reg=/\b sClass \b/g
            var reg= new RegExp(&#39;\\b&#39;+sClass+&#39;\\b&#39;,&#39;g&#39;);
            if(reg.test(aAll[i].className)){
                res.push(aAll[i]);
            }
        }
        return res;
    }
}
//如果参数是str 进行选择器的操作
function getByStr(aParent,str){
    //用来存放选中的元素的数组 这个数组在getEle存在,为了每次执行的时候都需要清空,所以使用局部函数的变量
    var aChild=[];
    //aParent开始是[document],再执行完getByStr的时候getEle将aParent指向了getByStr函数的返回值aChild数组以确保循环父级下面的所有匹配元素
    for(var i=0;i<aParent.length;i++){
        switch(str.charAt(0)){
            //id选择器  eg: #box  使用document.getElementById选取
            case &#39;#&#39;:
                var obj=document.getElementById(str.substring(1));
                aChild.push(obj);
                break;
            //类选择器  eg: .box  使用上面封装的getByClass选取
            case &#39;.&#39;:
                //由于一个标签可以有多个类选择器 所以需要进行循环选取
                var aRes=getByClass(aParent[i],str.substring(1));
                for(var j=0;j<aRes.length;j++){
                    aChild.push(aRes[j]);
                }
                break;
            //今天先简单的编写选择器  这里我们假设除了id和类选择器,就是标签选择器
            default:
              // 如果是li.red  那么用正则来判断
                if(/\w+\.\w+/g.test(str)){
                    //先选择标签,在选择类选择器  使用类选择器的时候重复选择器函数即可
                    var aStr=str.split(&#39;.&#39;);
                    var aRes=aParent[i].getElementsByTagName(aStr[0]);
                    var reg=new RegExp(&#39;\\b&#39;+aStr[1]+&#39;\\b&#39;,&#39;g&#39;);
                    //循环选取标签,注意外层已经有i的循环
                    for(var j=0;j<aRes.length;j++){
                        if(reg.test(aRes[j].className)){
                            aChild.push(aRes[j]);
                        }
                    }
                //如果是li:eq(2) 或者 li:first这样的选择器   书写正则是的时候注意()可有可以无为? 有或者没有为* 至少有一个也就是若干个为+   {2,5}这种则为2-5个
                }else if(/\w+\:\w+(\(\d+\))?/g.test(str)){
                    //讲str进行整理    [li,eq,2]  或者  [li,first]
                    var aStr=str.split(/\:|\(|\)/);
                    //aStr[2]是eq、lt、gt传入的参数,这里使用n来保存
                    var n=aStr[2];
                    //在父级下获取所有匹配aStr[0]项的标签
                    var aRes=aParent[i].getElementsByTagName(aStr[0]);
                    //这时候会循环判断aStr[1]项是的内容,jquery中经常使用的为eq、lt、gt、even、odd、first、last
                    switch(aStr[1]){
                        //如果是eq则把第n项传入aChild数组即可
                        case &#39;eq&#39;:
                            aChild.push(aRes[n]);
                            break;
                        //如果是lt需要将aRes数组中获取到的小于n的标签循环推入aChild中
                        case &#39;lt&#39;:
                            for(var j=0;j<n;j++){
                                aChild.push(aRes[j]);
                            }
                            break;
                        //如果是gt则和lt相反
                        case &#39;gt&#39;:
                           for(var j=n;j<aRes.legth;j++){
                               aChild.push(aRes[j]);
                           }
                            break;
                        //如果是event的话需要隔数添加,注意jquery中的event是从第0开始循环的
                        case &#39;event&#39;:
                            for(var j=0;j<aRes.length;j+=2){
                               aChild.push(aRes[j]);
                            }
                            break;
                        //如果是odd的和event不同的只是从第1项开始循环
                        case &#39;odd&#39;:
                            for(var j=1;j<aRes.length;j+=2){
                                aChild.push(aRes[j]);
                            }
                            break;
                        //如果是first,则将aRes[0]推入aChild
                        case &#39;first&#39;:
                            aChild.push(aRes[0]);
                            break;
                        case &#39;last&#39;:
                            aChild.push(aRes[aRes.length-1]);
                            break;
                    }
                //属性选择器  eg:input[type=button] 同样适用正则来判断
                }else if(/\w+\[\w+\=\w+\]/g.test(str)){
                    //将属性选择器切成数组   [input,type,button]
                    var aStr=str.split(/\[|\=|\]/g);
                    var aRes=aParent[i].getElementsByTagName(aStr[0]);
                    //在选中标签中选出有aRes[1]的属性
                    for(var j=0;j<aRes.length;j++){
                        //把属性值为aRes[2]的标签推入aChild中
                        if(aRes[j].getAttribute(aStr[1])==aStr[2]){
                            aChild.push(aRes[j]);
                        }
                    }
                //标签选择器  p、span
                }else{
                    var aRes=aParent[i].getElementsByTagName(str);
                    for(var j=0;j<aRes.length;j++){
                        aChild.push(aRes[j]);
                    }
                }
                break;
        }
    }
    return aChild;
}
function getEle(str){
    //如果是字符串的话先要去除收尾空格  eg:"   on replace   index  play auto   "
    var arr = str.replace(/^\s+|\s+$/g,&#39;&#39;).split(/\s+/g);
    var aChild = [];
    var aParent = [document];
    for(var i = 0;i<arr.length;i++){
        aChild = getByStr(aParent,arr[i]);
        aParent = aChild
    }
    return aChild;
}
//实现jquery $符号的写法
function $(arg){
    return new Jquery(arg);
}
登入後複製

以上是jquery中類別選擇器的功能如何實作實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1247
24
vivox100s和x100區別:效能比較及功能解析 vivox100s和x100區別:效能比較及功能解析 Mar 23, 2024 pm 10:27 PM

vivox100s和x100手機都是vivo手機產品線中的代表機型,它們分別代表了vivo在不同時間段內的高端技術水平,因此這兩款手機在設計、性能和功能上均有一定區別。本文將從效能比較和功能解析兩個面向對這兩款手機進行詳細比較,幫助消費者更好地選擇適合自己的手機。首先,我們來看vivox100s和x100在效能上的比較。 vivox100s搭載了最新的

華為手機如何實現雙微信登入? 華為手機如何實現雙微信登入? Mar 24, 2024 am 11:27 AM

華為手機如何實現雙微信登入?隨著社群媒體的興起,微信已成為人們日常生活中不可或缺的溝通工具之一。然而,許多人可能會遇到一個問題:在同一部手機上同時登入多個微信帳號。對於華為手機用戶來說,實現雙微信登入並不困難,本文將介紹華為手機如何實現雙微信登入的方法。首先,華為手機自帶的EMUI系統提供了一個很方便的功能-應用程式雙開。透過應用程式雙開功能,用戶可以在手機上同

自媒體到底是什麼?它的主要特點和功能有哪些? 自媒體到底是什麼?它的主要特點和功能有哪些? Mar 21, 2024 pm 08:21 PM

隨著網路的快速發展,自媒體這個概念已經深入人心。那麼,自媒體到底是什麼呢?它有哪些主要特點和功能呢?接下來,我們將一一探討這些問題。一、自媒體到底是什麼?自媒體,顧名思義,就是自己就是媒體。它是指透過網路平台,個人或團隊可以自主創建、編輯、發布和傳播內容的資訊載體。不同於傳統媒體,如報紙、電視、電台等,自媒體具有更強的互動性和個人化,讓每個人都能成為訊息的生產者和傳播者。二、自媒體的主要特色和功能有哪些? 1.低門檻:自媒體的崛起降低了進入媒體產業的門檻,不再需要繁瑣的設備和專業的團隊,一部手

PHP程式設計指南:實作斐波那契數列的方法 PHP程式設計指南:實作斐波那契數列的方法 Mar 20, 2024 pm 04:54 PM

程式語言PHP是一種用於Web開發的強大工具,能夠支援多種不同的程式設計邏輯和演算法。其中,實作斐波那契數列是一個常見且經典的程式設計問題。在這篇文章中,將介紹如何使用PHP程式語言來實作斐波那契數列的方法,並附上具體的程式碼範例。斐波那契數列是一個數學上的序列,其定義如下:數列的第一個和第二個元素為1,從第三個元素開始,每個元素的值等於前兩個元素的和。數列的前幾元

小紅書帳號管理軟體有哪些功能?怎麼經營小紅書帳號? 小紅書帳號管理軟體有哪些功能?怎麼經營小紅書帳號? Mar 21, 2024 pm 04:16 PM

隨著小紅書在年輕人中的流行,越來越多的人開始利用這個平台分享各方面的經驗和生活見解。如何有效管理多個小紅書帳號成為關鍵問題。在本文中,我們將討論一些小紅書帳號管理軟體的功能,並探討如何更好地經營小紅書帳號。隨著社群媒體的發展,許多人發現自己需要管理多個社群帳號。對於小紅書用戶來說,這也是一個挑戰。一些小紅書帳號管理軟體可以幫助使用者更輕鬆地管理多個帳號,包括自動發佈內容、定時發布、資料分析等功能。透過這些工具,使用者可以更有效率地管理他們的帳號,提高帳號的曝光率和關注。另一、小紅書帳號管理軟體有

PHP技巧:快速實現返回上一頁功能 PHP技巧:快速實現返回上一頁功能 Mar 09, 2024 am 08:21 AM

PHP技巧:快速實現回到上一頁功能在網頁開發中,常常會遇到需要實作返回上一頁的功能。這樣的操作可以提高使用者體驗,讓使用者更方便地在網頁之間進行導航。在PHP中,我們可以透過一些簡單的程式碼來實現這項功能。本文將介紹如何快速實現返回上一頁功能,並提供具體的PHP程式碼範例。在PHP中,我們可以使用$_SERVER['HTTP_REFERER']來取得上一頁的URL

如何在華為手機上實現微信分身功能 如何在華為手機上實現微信分身功能 Mar 24, 2024 pm 06:03 PM

如何在華為手機上實現微信分身功能隨著社群軟體的普及和人們對隱私安全的日益重視,微信分身功能逐漸成為人們關注的焦點。微信分身功能可以幫助使用者在同一台手機上同時登入多個微信帳號,方便管理和使用。在華為手機上實現微信分身功能並不困難,只需要按照以下步驟操作即可。第一步:確保手機系統版本和微信版本符合要求首先,確保你的華為手機系統版本已更新至最新版本,以及微信App

掌握Golang如何實現遊戲開發的可能性 掌握Golang如何實現遊戲開發的可能性 Mar 16, 2024 pm 12:57 PM

在現今的軟體開發領域中,Golang(Go語言)作為一種高效、簡潔、並發性強的程式語言,越來越受到開發者的青睞。其豐富的標準庫和高效的並發特性使它成為遊戲開發領域的一個備受關注的選擇。本文將探討如何利用Golang來實現遊戲開發,並透過具體的程式碼範例來展示其強大的可能性。 1.Golang在遊戲開發中的優勢作為靜態類型語言,Golang正在建構大型遊戲系統

See all articles