《Ext JS实战》——2.2 Ext.Element类

简介: 这个getElementById方法很好用,可以执行一些类似改变innerHTML的内容,或者美化和配置一个CSS类这样的基本任务。不过要是想对该节点做更多的事情,例如管理它的事件,在有鼠标点击时应用某个样式,或者替换一个CSS类?必须自己管理全部代码,还要不断地对代码进行更新,以保证能够全部浏览器的兼容性。

本节书摘来自异步社区《Ext JS实战》一书中的第2章,第2.2节,作者:【美】Jesus Garcia著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.2 Ext.Element类

所有使用了JavaScript的Web应用程序都会围绕着一个核心,也就是HTML的Element。JavaScript对DOM节点的访问能力让我们能够随意、灵活地操作DOM,包括增加、删除、美化或者修改文档中的任意节点内容。通过ID引用一个DOM节点的传统方法是:

screenshot

这个getElementById方法很好用,可以执行一些类似改变innerHTML的内容,或者美化和配置一个CSS类这样的基本任务。不过要是想对该节点做更多的事情,例如管理它的事件,在有鼠标点击时应用某个样式,或者替换一个CSS类?必须自己管理全部代码,还要不断地对代码进行更新,以保证能够全部浏览器的兼容性。老实说,我想不起还有什么事情会比这个更费劲了。幸运的是,Ext都替我们完成了这些任务。

2.2.1 框架的核心
先看一下Ext.Element这个类,Ext JS社区公认这个类是Ext JS的核心,框架中的每个UI部件中都有它的身影,通过getEl()方法或者el属性都可以得到它。

Ext.Element类是一个完整的DOM元素管理包,包含了许多宝贵的工具,正是因为它的存在,才使得框架能够对DOM施展魔法,并提供健壮的UI供我们使用。这个工具集及其全部的功能对于最终的开发人员都是可用的。

按照Ext JS的设计理念,这个类不仅仅是对DOM元素的简单管理,还能处理各种复杂的任务,例如能够很容易地管理大小、对齐以及坐标。也可以很容易地利用Ajax更新一个元素,管理子节点、动画,使用完整的事件管理以及更多的内容。

2.2.2 与Ext.Element的第一次亲密接触
Ext.Element是很容易上手的,而且可以简化一些最困难的任务,为了练习Ext.Element,需要配置一个基本页面。按照第1章介绍的方法,配置一个包含了Ext JavaScript和CSS的页面。接下来,要包含下面的CSS和HTML:

screenshot

这些只是给我们的示例搭建一个舞台,确保div标签有明确的大小和边框,这样在页面上能够清晰地看到效果。这里用了一个id是'div1'的div,它就是要操作的目标。如果页面设置正确无误,应该可以清楚地看到这个样式化的,如图2-2所示。这幅图片展示的是一个普通的HTML框,下面就用它来练习基本的Ext.Element方法。

screenshot

注意:
所有的关于Ext.Element的示例代码都会引用刚刚配置的基本页面。如果想真切地看到DOM发生的改变,建议用Firefox内置的多行的Firebug文本编辑器。相反,可以把这些示例放在一般的脚本块中。只是记住要使用Ext.onReady()。
按照这个CSS定义,属于muDiv类的div都会是35个像素高和200个像素宽,看起来有点怪异。我们要做的就是,通过把高度改成200个像素,让这个div变成一个完美的正方形。

screenshot

上面这两行代码的执行非常重要。第一行使用的是Ext.get,传给这个方法一个字符串'div',返回的结果是一个Ext.Element的实例,返回的实例通过变量myDiv1进行引用。Ext.get使用的也是document.getElementById,只不过是按照Ext的元素管理方法对它进行了包装而已。

得到这个Ext.Element实例myDiv1之后,通过调用它的setHeight方法,并传入一个整数值200,就把这个方框的高度增加到了200个像素。类似地,也可以用setWidth方法改变元素的宽度,不过下面会跳到一些更有趣的内容。

“一个完美的正方形。不错!”好了,再把大小改变一下,这次使用的是setSize。把width和height都设成350个像素。还是利用已经创建好的引用,myDiv1:

screenshot

执行这行代码会发生什么呢?是不是动起来了,有一种生动的效果?更好了!

实际上,setSize方法是setHeight和setWidth方法的组合。对这个方法,传递的是宽度,高度以及一个带有两个属性的对象,这两个属性是duration和easing。如果定义了第3个属性,会让setSize以动画的效果展现元素大小的改变。如果不在乎动画效果,那就可以忽略第3个参数,这个框的大小立刻会发生改变,就像之前改变高度那样。

设置大小还只是通过Element类管理元素的众多功能之一。Ext.Element更强大的能力体现在轻松地处理元素的CRUD操作(创建、读取、更新和删除)。

2.2.3 创建子节点
JavaScript的好处之一就是操纵DOM的能力,这其中就包括DOM节点的创建。JavaScript中的有很多原生方法也具有这个能力。Ext JS用Ext.Element类很方便地把这些方法包装起来。下面看看如何创建子节点。

要想创建一个子节点,要用的是Element的createChild方法:

screenshot

这段代码给目标div的innerHTML添加了一个字符串节点。如果想创建一个元素该怎么做呢?很简单:

screenshot

createChild会给div1的innerHTML追加一个内容是字符串'Element from a string'的子Div。我不喜欢用这种方法追加子元素,因为这种用字符串代表元素的形式太混乱了。Ext通过接收一个配置对象而不是一个字符串帮我们解决了这个问题:

screenshot

这里是通过配置对象来创建子元素的。将tag属性设成'div',给html属性指定了一个字符串。单从技术的角度来看,这个方法和之前的createChild实现是一样的,不过看起来更清晰,更能说明我们的意图。如果想注入一个嵌套的标签又该怎么做呢?还是通过配置对象的方法,可以很容易地实现:

screenshot

在这段代码中,创建了最后一个子元素,它有一个id、一些样式以及一个子元素,这个子元素是一个带有更多样式的div。图2-3显示了div所发生的变化。

screenshot

在图2-3中,可以看到添加到myDiv1的全部内容,以及Firebug所展示的一副生动的DOM视图,这里增加了一个字符串节点和3个子div,其中一个还有它自己的子div。

如果想在列表的顶端插入一个子元素,还可以使用好用的insertFirst方法,例如:

screenshot

Element.insertFirst总是在位置0插入一个新的元素,即使DOM结构中还没有一个子元素也一样。

如果想在一个特定的位置插入一个子节点,createChild方法也可以完成这个任务。我们所要做的就是把新创建节点的位置传进去,例如:

screenshot

在这段代码中,我们给createChild传入了两个参数。第一个参数是个配置对象,代表着新创建的DOM元素,第二个参数是目标节点的引用,createChild用它作为新建节点的容身之所。记住你给这个新创建元素指定的id;我们很快就会用到它。

注意,这里用到了myDiv1.dom.childNodes。Ext.Element的dom属性让我们具有了利用通用浏览器元素管理优雅性的机会。

注意:
Element.Dom属性和document.getElementById()返回的是同样的DOM元素引用。
图2-4显示了在页面上看到的插入节点的样子,以及在Firebug的DOM探测工具中看到的DOM层次结构。从图2-4中可以看到,节点插入的结果和我们设想的一样。用insertFirst在列表的顶端插入一个新节点,用createChild在子节点3的上面插入一个节点。记住,对子节点的计数总是从数字0开始的,而不是从1开始的。

screenshot

作为一名Web开发人员,添加元素对我们来说是家常便饭。毕竟,这是DHTML的一部分。不过删除也同样重要。下面再看看如何用Ext.Element删除一些子元素。

2.2.4 删除子节点
节点的删除看起来要比添加简单一些。我们所需要做的就是通过Ext找到该节点,然后调用节点自己的remove方法就行了。为了练习子节点的删除操作,以一个干净的画板开始。请新建一个页面,然后输入下面的HTML代码:

screenshot

检查这段HTML代码,看到了一个id是'div1'的父div。它有5个直系的后代,第1个的id是'child1'。第2个和第3个没有id,不过其CSS类分别是'child2'和'child3'。第4个子元素的id是'child4',并且其CSS类是'sameClass'。类似地,它也有一个id是'nestedChild1'的直系后代,并且用的是和父亲相同的CSS类。Div1的最后一个孩子没有id,也没有CSS类。之所以准备这些素材,是因为要先从CSS选择器1开始,然后再到直接利用元素的id。

在添加子节点的例子中,一直是把父div(id='div1')包装成Ext.Element后加以引用,然后用它的create方法创建节点。要想删除一个节点,就要用不同的方法了,因为需要明确地定位到要删除的节点。对于这个新的DOM结构,我们会用几种方法来实现。

要尝试的第一个方法是通过一个已经包装好的DOM元素删除一个子节点。先要创建一个包装div1的Ext.Element实例,然后再用CSS选择器找到它的第一个子节点。
screenshot

这个例子中,通过Ext.get得到了对div1的引用。然后又调用了Element.down方法,传给这个方法的是一个伪类选择器,这会让Ext沿着这棵DOM树向下查找,一直到找到第一个孩子,它是一个div,然后Ext把它包装成一个Ext.Element的实例,最终得到的就是对第一个子元素的引用,即firstChild的引用。

Element.down方法查找的是给出的Ext.Element的一级DOM节点。找到的结果恰好是一个id是'child1'的div。然后调用firstChild.remove,这个节点就从DOM中删除了。

下面是通过选择器删除列表中的最后一个节点:

screenshot

这个例子和前一个类似,最大的区别在于用的是选择器'div:last-child',这个选择器找到div1的最后一个childNode,然后再用一个Ext.Element的实例把它封装起来。最后,再调用lastChild.remove,这个节点就没有了。

如果想根据id找到目标元素该怎么办呢?可以让Ext.get完成这个工作。这次,没有必要创建引用,用链(Chaining)完成这个工作就可以了:

screenshot

执行这行代码会把id是'child4'的子节点删掉,包括该节点的子节点。记住,如果一个节点有子节点,那么删除这个节点的同时,它的所有子节点也都会被删除。

关于Ext.Element要了解的最后一项内容就是执行Ajax请求,从服务器远程加载HTML片段并把它们注入到DOM中。

2.2.5 Ext.Element与Ajax一起使用
Ext.Element类具有执行Ajax的能力,可以取得远程的HTML片段,并把这些片段注入到它自己的innerHTML中。做练习之前,先写一个将要被加载的HTML片段:

screenshot

这个HTML片段中,只放了一个简单的div,还嵌入了一个script脚本,里面调用的是Ext.getBody,然后又通过链调用它的highlight方法。要想得到对document.body的引用,Ext.getBody非常好用,现在把这个文件保存成htmlFragment.html。

接着,要加载以下内容。

screenshot

这段代码中,调用的是Ext.getBody所返回的对象的load方法,并给这个方法传入一个配置对象,其中url指定的要加载的目标htmlFragment.html,scripts被设为true。这段代码执行起来会怎么样呢?可以参见图2-5。

screenshot

这段代码执行后,可以看到文档体通过Ajax请求获取了htmlFragment.html文件。在获取这个文件的过程中,会一直显示一个代表正在加载的指示符,一旦请求完成,这段HTML片段就被插入到DOM中了。接着会看到整个内容区都用黄色高亮显示,这就意味着JavaScript代码得到了执行。现在,应该知道Ext.Element.load方法要比手工调用Ext.Ajax.request方便多了。

看到了吧,用Ext.Element给DOM添加内容或者删除内容就是小菜一碟。Ext还有更简单的办法添加元素,尤其是当要增加的是那种重复的DOM结构。这就要用到Template和XTemplate两个辅助工具类。

相关文章
|
2月前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
22天前
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
17天前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
17天前
Next.js 实战 (三):优雅的实现暗黑主题模式
这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
|
1月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
31 2
|
2月前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
39 1
|
2月前
|
SQL 前端开发 JavaScript
Nest.js 实战 (十五):前后端分离项目部署的最佳实践
这篇文章介绍了如何使用现代前端框架Vue3和后端Node.js框架Nest.js实现的前后端分离架构的应用,并将其部署到生产环境。文章涵盖了准备阶段,包括云服务器的设置、1Panel面板的安装、数据库的安装、域名的实名认证和备案、SSL证书的申请。在部署Node服务环节,包括了Node.js环境的创建、数据库的配置、用户名和密码的设置、网站信息的填写、静态网站的部署、反向代理的配置以及可能遇到的常见问题。最后,作者总结了部署经验,并希望对读者有所帮助。
212 11
|
3月前
|
Web App开发 JavaScript 前端开发
JavaScript 类(class)
JavaScript 类(class)
29 2
JavaScript 类(class)
|
2月前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
2月前
|
数据采集 JSON 前端开发
JavaScript逆向爬虫实战分析
JavaScript逆向爬虫实战分析
44 4