`
coconut_zhang
  • 浏览: 542064 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

通过Class Name获取一个对象的数组

 
阅读更多

DOM 提供了一个名为 getElementById() 的方法,这个方法将返回一个对象,这个对象就是参数 id 所对应的元素节点。另外,getElementByTagName() 方法会返回一个对象的数组,每一个对象分别对应着文档里有给定标签的一个元素。这个方法的参数是 html 标签的名字。现在我们考虑一个问题,能不能通过标签的类名class name来获取该对象呢?下面是这个猜想的程序实现(支持多个class查询和在某个范围内进行查询):

 /*
 * 根据元素clsssName得到元素集合
 * @param fatherId 父元素的ID,默认为document
 * @tagName 子元素的标签名
 * @className 用空格分开的className字符串
 */
function getElementsByClassName(fatherId,tagName,className){
 node = fatherId&&document.getElementById(fatherId) || document;
 tagName = tagName || "*";
 className = className.split(" ");
 var classNameLength = className.length;
 for(var i=0,j=classNameLength;i<j;i++){
  //创建匹配类名的正则
  className[i]= new RegExp("(^|\\s)" + className[i].replace(/\-/g, "\\-") + "(\\s|$)");
 }
 var elements = node.getElementsByTagName(tagName);
 var result = [];
 for(var i=0,j=elements.length,k=0;i<j;i++){//缓存length属性
  var element = elements[i];
  while(className[k++].test(element.className)){//优化循环
   if(k === classNameLength){
    result[result.length] = element;
    break;
   } 
  }
  k = 0;
 }
 return result;
}
好,我们来测试一下:

<div id="container">
   <span class="aaa zzz ccc"></span>
   <div class="aaa bbb ccc"></div>
</div>
<div class="aaa bbb ccc"></div>

正确的得到了结果。

有人会问,原生的方法调用效率是最高的,有很多浏览器已经将实现了getElementsByClassName这个方法,那为什这里没有先调用原生的再调用自定义的呢?

对,原生的效率是很高,它支持多个class条件的查询,但是最大的问题是他不支持getElementsByClassName("container","div","aaa ccc"),这种在指定标签中查找指定元素为指定class的情况。所以,这里舍弃了原生的方法调用。

在代码中,你会看到我将数组的length缓存了起来,这样可以提高效率。其实上,在这里有一个很隐蔽的问题,就是数组访问length属性和HtmlCollection访问length有很在的区别。在数组中,length是一个普通的属性,访问时不会进行额外的操作,在来看看HTMLCollection,我们常常将HTMLCollection当作数组来使用,但实际上,它是一个根据DOM结构自动变化的实体对象。每次访问一个HTMLCollection对象的属性时,他都会对DOM内所有的节点进行一次完整的匹配。也就是说,每次访问HtmlCollection对象的length时,都会更新一次集合对象,性能上消耗很大。所以一般情况之下,这种HtmlCollection的循环操作,都是建议缓存length的。

小插曲

这是关于往数组里放元素的方式间,效率比较的问题。来看一下代码:

//方式一
var arr = [];
var start = new Date();
for(var i=0;i<100000;i++){
 arr.push(i);
}

//方式二
var arr = [];
var start = new Date();
for(var i=0;i<100000;i++){
 arr[arr.length]=i;
}

猜猜看,哪种效率更高呢!经过测试,第二种方式的效率要高于第一种。好了,不多说的,这个函数简单实用,代码上我也写了注释,看应该已经没有什么问题了。

分享到:
评论

相关推荐

    Intent传递对象、对象数组

    本话题将详细探讨如何通过Intent传递对象以及对象数组。 一、Intent的基础 Intent主要由两部分构成:Action(动作)和Data(数据)。Action定义了Intent要执行的操作,如ACTION_VIEW、ACTION_SEND等;Data则包含了...

    jni返回对象数组例子

    本示例主要探讨如何在JNI中创建并返回一个对象数组到Java层。 首先,我们需要定义一个Java类,这个类将包含JNI方法的声明。例如,我们可能有一个`Person`类,表示一个人的信息: ```java public class Person { ...

    ActionForm属性中存在对象数组如何处理

    在Struts框架中,ActionForm类是...4. 在Action类中从ActionForm中获取对象数组,并进行进一步处理。 通过这种方式,Struts框架能够处理ActionForm中包含对象数组的场景,允许用户在一次表单提交中处理多个对象实例。

    ajax传递list对象数组

    本篇将详细介绍如何通过AJAX来传递一个List对象数组,并解析其中涉及到的关键技术点。 #### 二、知识点概览 1. **前端JavaScript处理List对象数组** 2. **使用jQuery的$.ajax方法发送POST请求** 3. **后端接收List...

    对象数组便历及查找.zip

    1. 定义一个类,比如`class Person { String name; int age; }` 2. 创建对象数组,如`Person[] people = new Person[5];` 3. 使用`new`关键字实例化每个数组元素,如`people[0] = new Person();` 遍历对象数组通常...

    利用对象数组对员工,学生增删改查

    接下来,我们创建一个对象数组,比如`Employee[] employees`或`Student[] students`,并用它来存储创建的对象实例。我们可以使用for循环遍历数组,执行增删改查操作。 例如,添加一个新的员工或学生: ```java ...

    Vue监听一个数组id是否与另一个数组id相同的方法

    &lt;div class=hello&gt; &lt;div class=shoplist&gt; &lt;button @click=clickButtonShopList&gt;click me&lt;/button&gt; &lt;span&gt;shoplist-id:&lt;/span&gt;&lt;input type=text v-model=shoplist[shopCount].id&gt;

    Class对象获取的三种方法

    使用`.class`语法获取`Class`对象的一个优势在于它不需要创建任何类的实例,因此效率较高,适用于只需要类型信息而不涉及实例操作的场景。 ### 2\. 使用`Class.forName(String name)`方法获取`Class`对象 `Class....

    xfire 使用外部类、返回collection及输入数组参数示例

    假设我们需要一个服务接收一组ID,然后根据这些ID获取对应的`Person`对象: ```java public List&lt;Person&gt; getPersonsByIds(int[] ids); ``` Xfire会将传入的XML数组解析为Java数组,并传递给服务方法。 ### 实现...

    Java技术对接收数组参数的成员方法进行反射

    1. 获取类的Class对象:通过`Class.forName()`方法或对象的`getClass()`方法,我们可以获取到任何类的`Class`对象,这为我们提供了关于该类的所有元数据。 2. 获取方法:使用`Class`对象的`getMethod()`或`...

    java实现数组实例化一个类

    本文将详细探讨如何使用Java语言创建一个`Student`类,并通过数组来实例化该类的对象。 #### 创建 Student 类 首先,我们需要定义一个`Student`类,它包含三个私有属性:姓名(`name`)、年级(`grade`)以及所学...

    把实体类数组转换为DataTable C#

    当我们有一个实体类数组,可能是因为我们从数据库查询了数据并将其封装在实体类对象中,然后想要将这些数据转换成DataTable,以便进行进一步的数据操作或绑定到控件上。 要实现这个转换,我们需要以下步骤: 1. ...

    hibernate array 数组映射

    Hibernate 是一个开源的Java ORM(Object-Relational Mapping)框架,它通过提供一种对象-关系映射机制,使得开发者可以使用面向对象的方式来操作数据库,从而避免了传统的JDBC繁琐的数据库操作。 ### 数组映射原理...

    vue遍历对象中的数组取值示例

    在Vue.js中,遍历对象中的数组并获取其值是一个常见的需求,特别是在处理从后端获取的数据时。本文将通过一个具体的示例来讲解如何在Vue中实现这一操作。 首先,我们看一段代码,这是在Vue组件中遍历对象数组并显示...

    c#面向对象控制台-通讯录数组添加联系人

    通过以上步骤,你将能够创建一个简单的C#控制台应用,允许用户输入联系人信息并将其存储在一个数组中。这只是一个基本示例,实际项目可能需要考虑更多的功能,如搜索、删除联系人,或者使用文件存储联系人数据以便...

    【Intent传递】对象、数组 DEMO

    本DEMO重点展示了如何通过Intent来传递对象和数组,这是一个非常实用且常见的技能点。下面我们将深入探讨Intent的使用以及如何在Intent中携带对象和数组。 1. **Intent的基本概念** Intent是一个消息对象,用来...

    java.lang.Class类

    6. isArray():判定此Class对象是否表示一个数组类。 在实际应用中,Class类的使用技巧包括: 1. 使用forName和newInstance结合起来,可以根据存储在字符串中的类名创建对象。 2. 使用Class类可以实现类的反射机制...

    java反射机制学习(二):通过反射获取构造方法并实例化对象

    当我们知道一个类的名字(例如,"SUser"),我们可以通过`Class.forName()`方法获取该类的`Class`对象。这个`Class`对象就像是类的蓝图,提供了关于类的各种信息,包括它的构造方法、字段和方法。 在Java中,`...

    JS传递对象数组为参数给后端,后端获取的实例代码

    在JavaScript中,我们可以创建一个对象数组,然后通过Ajax方式发送到服务器。下面是一个简单的示例: ```javascript // 创建对象数组 var conditions = []; var test1 = new Object(); test1.name = "1"; test1.id ...

    c#利用Newtonsoft.Json解析json(带数组)

    本教程将深入探讨如何使用Newtonsoft.Json库在C#中解析包含数组的JSON对象,这对于处理从Web API、数据库或其他服务获取的复杂数据至关重要。 首先,我们需要了解Newtonsoft.Json库,它也被称为Json.NET,是一个...

Global site tag (gtag.js) - Google Analytics