DOM操作全解析
1. 常用函数介绍
在进行DOM操作时,有几个常用的函数能极大地提高开发效率。
-
$()
函数
:它是
document.getElementById()
的特殊封装。与
document.getElementById()
不同的是,
$()
可以接受多个参数,并返回包含所有请求元素的数组。如果参数不是字符串,会直接传递。例如:
// <p id="one">One</p>
// <p id="two">Two</p>
$('one').toString();
// => '[object HTMLParagraphElement]'
$('one','two').toString();
// => [object P],[object P]
$($('one')).toString();
// => [object HTMLParagraphElement]
-
$F()函数 :用于返回任何字段输入控件(如文本框或下拉列表)的值。element可以是ID字符串或元素对象本身。示例如下:
// <input type="text" id="userName" value="Joe Doe">
// <select id="state">
// <option value="NY">New York</option>
// <option value="CA" selected="selected">California</option>
// </select>
$F('userName');
// => "Joe Doe"
$F('state');
// => "CA"
2. 选择器
Selector
类及其伴随的
$$()
方法允许通过CSS选择器引用页面元素,使用与CSS文件中相同的语法。
$$()
方法接受一个或多个CSS选择器表达式,并返回匹配的元素。
-
示例代码
:
$$('form#foo input[type=text]').each(function(input) {
input.setStyle({color: 'red'});
});
上述代码选择了ID为
foo
的表单元素下的所有文本字段,并将它们的颜色设置为红色。
-
其他可能的表达式
:
- 按标签名(包括通配符):
$$('strong')
、
$$('*')
- 按ID和类:
$('#foo')
、
$$('.bar')
- 按标签、ID和类的组合:
$$('strong#foo')
、
$$('string.bar')
等
- 按祖先元素:
$$('#foo strong *')
、
$$('strong#foo span')
- 按属性存在性:
$$('h1[class]')
- 按属性值和否定值:
$$('a[href="#"]')
、
$$('a[href!=#]')
- 按空格分隔的属性值:
$$('a[class~="internal"]')
- 按连字符分隔的属性值:
$$('*[xml:lang|="es"]')
- 按多个属性条件:
$$('a[class~=external][href="#"]')
- 组合多个表达式:
$('#foo', '#bar')
Selector
类还提供了一些方法:
| 方法 | 描述 |
| ---- | ---- |
|
initialize( expression )
| 为表达式创建一个新的选择器实例 |
|
findElements([ scope ])
| 返回所有匹配选择器表达式的元素,这些元素是
scope
元素的子元素(默认为整个文档) |
|
match( element )
| 如果元素匹配选择器表达式,则返回
true
|
|
toString( )
| 返回选择器表达式的字符串表示 |
|
matchElements( elements , expression )
| 静态方法,返回匹配表达式的元素子集 |
|
findElement( elements , expression [, index ])
| 静态方法,返回匹配表达式的第一个元素。如果提供了
index
,则返回第
n
个匹配元素 |
|
findChildElements( element , expressions )
| 静态方法,返回从
element
派生的、匹配
expressions
数组中任何表达式的元素数组 |
以下是一些使用示例:
// Create a Selector instance
fooFinder = new Selector('.foo');
// Find all elements in the document with the class 'foo'
fooFinder.findElements();
// Find all elements within the 'container' element with the class 'foo'
fooFinder.findElements($('container'));
// Determine whether the 'bar' element has the class 'foo'
fooFinder.match($('bar'));
// Find all elements with class 'foo' from the descendants of 'container'
Selector.matchElements($('container').descendants(), '.foo');
// Find the first element with the class 'foo' from the descendants of 'container'
Selector.findElement($('container').descendants(), '.foo');
// Find the second element with the class 'foo' from the descendants of 'container'
Selector.findElement($('container').descendants(), '.foo', 1);
// Find all elements with the class 'foo' within 'container'
Selector.findChildElements($('container'), ['.foo']);
// Find all elements with the class 'foo' or the class 'bar' within 'container'
Selector.findChildElements($('container'), ['.foo', '.bar']);
另外,
document.getElementsByClassName(className [, parentElement])
方法返回与CSS类
className
关联的所有元素。如果未提供
parentElement
,则会搜索整个文档主体。
3. 元素方法
提供了用于操作页面元素的方法,这些方法可以通过两种方式访问。
-
作为函数访问
:
Element.toggle('target');
var myElement = $('target2');
Element.update(myElement, 'Hello');
上述代码切换了ID为
target
的元素的可见性,并将
myElement
元素的内容替换为
Hello
。
-
作为页面元素对象的方法直接访问
:每当通过Prototype的
$()
或
$$()
函数引用元素时,
Element.Methods
中的所有方法都会复制到元素对象中。示例如下:
$('target').toggle();
var myElement = $('target2');
myElement.update('Hello');
许多方法会返回它们操作的元素,从而实现方便的链式调用。例如:
$('target').update('Hello').addClassName('big').show();
以下是一些常用的元素方法:
| 方法 | 描述 |
| ---- | ---- |
|
hide( element )
| 通过将元素的显示样式设置为
none
来隐藏元素,返回元素 |
|
show( element )
| 通过将元素的显示样式重置为空来显示元素,返回元素 |
|
toggle( element )
| 切换元素的可见性,返回元素 |
|
visible( element )
| 返回一个布尔值,指示元素是否可见 |
|
empty( element )
| 返回一个布尔值,指示元素的标签是否为空(或只有空白) |
|
remove( element )
| 从文档中移除元素,返回元素 |
|
update( element , html )
| 用
html
替换元素的内部HTML。如果
html
包含
<script>
块,它们将不包含在内,但会被评估,返回元素 |
|
replace( element , html )
| 跨浏览器实现“outerHTML”属性,用
html
替换整个元素(包括其开始和结束标签),返回元素 |
|
classNames( element )
| 返回一个表示与元素关联的CSS类名的
Element.ClassNames
对象 |
|
hasClassName( element , className )
| 如果元素的类名中包含
className
,则返回
true
|
|
addClassName( element , className )
| 将
className
添加到与元素关联的CSS类名列表中,返回元素 |
|
removeClassName( element , className )
| 从与元素关联的CSS类名列表中移除
className
,返回元素 |
|
getStyle( element , cssProperty )
| 返回元素中CSS属性
cssProperty
的值(格式为
prop-name
或
propName
),如果不存在则返回
null
|
|
setStyle( element , cssPropertyHash )
| 根据
cssPropertyHash
哈希中的值设置元素的CSS属性值,返回元素 |
|
readAttribute( element , name )
| 返回元素名为
name
的属性的值 |
|
getDimensions( element )
| 返回元素的尺寸,返回值是一个包含
height
和
width
属性的对象 |
|
getHeight( element )
| 返回元素的
offsetHeight
|
|
makeClipping( element )
| 将元素的溢出样式设置为
hidden
,保存先前的值,返回元素 |
|
undoClipping( element )
| 将元素的溢出样式恢复到先前的状态,返回元素 |
|
makePositioned( element )
| 将元素的位置样式设置为
relative
,返回元素 |
|
undoPositioned( element )
| 将元素的位置样式设置为空,返回元素 |
|
scrollTo( element )
| 将窗口滚动到元素的位置,返回元素 |
|
cleanWhitespace( element )
| 移除元素的任何空白文本节点子元素,返回元素 |
|
ancestors( element )
| 返回元素的所有祖先元素的数组 |
|
descendants( element )
| 返回元素的所有后代元素的数组 |
|
immediateDescendants(element)
| 返回元素的不包含文本节点的子节点数组 |
|
siblings( element )
| 返回元素的所有兄弟元素的数组 |
|
previousSiblings( element )
| 返回元素在树中之前的所有兄弟元素的数组 |
|
nextSiblings( element )
| 返回元素在树中之后的所有兄弟元素的数组 |
|
up( element [, expression ][, index ])
| 返回元素的第一个祖先元素,可选择匹配CSS选择器表达式。如果提供了
index
,则返回第
n
个匹配元素 |
|
down( element [, expression ][, index ])
| 返回元素的第一个子元素,可选择匹配CSS选择器表达式。如果提供了
index
,则返回第
n
个匹配元素 |
|
previous( element [, expression ][, index ])
| 返回元素的第一个前一个兄弟元素,可选择匹配CSS选择器表达式。如果提供了
index
,则返回第
n
个匹配元素 |
|
next( element [, expression ][, index ])
| 返回元素的第一个下一个兄弟元素,可选择匹配CSS选择器表达式。如果提供了
index
,则返回第
n
个匹配元素 |
|
getElementsByClassName( element, className )
| 返回元素的所有具有类
className
的后代元素的数组 |
|
getElementsBySelector( element, expression1[, expression2 [...] )
| 返回元素的所有匹配任何给定CSS选择器表达式的后代元素的数组 |
|
recursivelyCollect( element , property )
| 递归返回与元素根据
property
相关的所有元素的数组 |
|
match( element, selector )
| 接受单个CSS选择器表达式(或
Selector
实例),如果匹配元素则返回
true
|
|
childOf( element, ancestor )
| 如果元素是
ancestor
的后代,则返回
true
|
|
observe( element, name, observer [ , useCapture ])
| 为元素添加一个事件处理函数
observer
,用于处理名为
name
的事件(如
click
、
load
等)。如果
useCapture
为
true
,则在捕获阶段处理事件;如果为
false
,则在冒泡阶段处理事件,返回元素 |
|
stopObserving( element, name, observer [ , useCapture ])
| 从元素中移除名为
name
的事件处理程序。
observer
是函数引用(不是匿名函数)。如果
useCapture
为
true
,则在捕获阶段处理事件;如果为
false
,则在冒泡阶段处理事件,返回元素 |
|
hasAttribute( element , attribute )
| 如果元素具有名为
attribute
的属性,则返回
true
|
|
inspect( element )
| 返回元素的字符串表示,用于调试,包括其名称、ID和类 |
以下是一个简单的mermaid流程图,展示了元素方法的调用流程:
graph LR
A[获取元素] --> B[调用元素方法]
B --> C{是否链式调用}
C -- 是 --> B
C -- 否 --> D[结束操作]
4. 表单相关操作
-
表单对象方法
:
Form对象提供了专门用于处理表单的额外元素方法。这些方法会自动添加到通过$()和$$()访问的元素中,但仅当元素是表单时才会添加。-
serialize( element ):返回元素的字段名和值的URL格式字符串。 -
serializeElements( elements ):返回元素的字段名和值的URL格式字符串。 -
findFirstElement( element ):返回元素中的第一个启用的字段元素。 -
getElements( element ):返回包含元素中所有输入字段的数组。 -
getInputs( element [, typeName [, name ]]):返回包含元素中所有<input>元素的数组。可选择根据元素的typeName或name属性过滤列表。 -
disable( element ):禁用表单中的所有输入字段,返回元素。 -
enable( element ):启用表单中的所有输入字段,返回元素。 -
focusFirstElement( element ):激活表单中第一个可见、启用的输入字段,返回元素。 -
reset( element ):将表单重置为其默认状态,返回元素。
-
示例代码:
// <form id="target"><input type="text" name="foo" value="bar" /></form>
Form.serialize('target'); // => "foo=bar"
$('target').serializeElements(); // => "foo=bar"
$('target').findFirstElement();
$('target').getElements();
$('target').getInputs();
$('target').getInputs('text');
$('target').getInputs('text', 'foo');
$('target').disable();
$('target').enable();
$('target').focusFirstElement();
$('target').reset();
-
表单元素对象方法
:
Form.Element对象(别名Field)提供了专门用于处理表单字段的额外元素方法。这些方法会自动添加到通过$()和$$()访问的元素中,但仅当元素是表单字段时才会添加。-
serialize( element ):返回元素的name=value字符串。 -
getValue( element ):返回元素的值。 -
clear( element ):清除元素的值,返回元素。 -
present( element ):如果元素包含非空值,则返回true。 -
focus( element ):将输入焦点移动到元素,返回元素。 -
select( element ):选择元素中支持文本选择的值,返回元素。 -
activate( element ):移动焦点并选择元素中支持文本选择的值,返回元素。 -
disable( element ):禁用元素的输入,返回元素。 -
enable( element ):启用元素的输入,返回元素。
-
示例代码:
// <input id="target" type="text" name="foo" value="bar" />
$('target').serialize(); // => "foo=bar"
$('target').getValue(); // => "bar"
$('target').clear();
$('target').present(); // => true
$('target').focus();
$('target').select();
$('target').activate();
$('target').disable();
$('target').enable();
5. Element.ClassNames类
Element.ClassNames
类代表与元素关联的CSS类名集合,提供了一系列操作类名的方法。
| 方法 | 描述 |
| ---- | ---- |
|
initialize( element )
| 创建一个表示元素CSS类名的
Element.ClassNames
对象 |
|
add( className )
| 将
className
包含在与元素关联的类名列表中 |
|
remove( className )
| 从与元素关联的CSS类名列表中移除
className
|
|
set( className )
| 将元素与
className
关联,并移除元素的任何其他类名 |
此外,
Element.ClassNames
还扩展了
Enumerable
方法,方便对类名进行遍历等操作。以下是使用示例:
// 创建Element.ClassNames对象
var classNamesObj = new Element.ClassNames($('target'));
// 添加类名
classNamesObj.add('newClass');
// 移除类名
classNamesObj.remove('oldClass');
// 设置类名
classNamesObj.set('singleClass');
6. 动态内容插入
Abstract.Insertion
用作其他提供动态内容插入的类的基类。它有几个重要的属性:
-
adjacency
:一个字符串,指定内容相对于给定元素的放置位置,可能的值为
beforeBegin
、
afterBegin
、
beforeEnd
和
afterEnd
。
-
element
:插入操作将相对于其进行的元素对象。
-
content
:要插入的内容。
基于
Abstract.Insertion
,有以下几个具体的插入类:
| 类名 | 描述 |
| ---- | ---- |
|
Insertion.Before
| 继承自
Abstract.Insertion
,初始化时将内容插入到元素之前 |
|
Insertion.Top
| 继承自
Abstract.Insertion
,初始化时将内容插入到元素下的第一个子元素位置,即元素的开始标签之后 |
|
Insertion.Bottom
| 继承自
Abstract.Insertion
,初始化时将内容插入到元素下的最后一个子元素位置,即元素的结束标签之前 |
|
Insertion.After
| 继承自
Abstract.Insertion
,初始化时将内容插入到元素的结束标签之后 |
以下是使用示例:
// <span id="name">Douglas</span>
new Insertion.Before('name', 'Hello, ');
new Insertion.Top('name', 'Scott ');
new Insertion.Bottom('name', ' Raymond');
new Insertion.After('name', '.');
下面是一个mermaid流程图,展示动态内容插入的流程:
graph LR
A[创建插入对象] --> B{选择插入位置}
B -- beforeBegin --> C[插入到元素之前]
B -- afterBegin --> D[插入到元素开始标签后]
B -- beforeEnd --> E[插入到元素结束标签前]
B -- afterEnd --> F[插入到元素之后]
7. 元素定位
Position
对象提供了许多有助于元素定位的函数。
| 方法 | 描述 |
| ---- | ---- |
|
prepare( )
| 调整
deltaX
和
deltaY
属性以适应滚动位置的变化。在页面滚动后调用
withinIncludingScrolloffset
之前,记得调用此方法 |
|
realOffset( element )
| 返回一个数组
[left, top]
,包含元素的滚动偏移量,包括影响它的任何滚动偏移量 |
|
cumulativeOffset( element )
| 返回一个数组
[left, top]
,包含元素及其所有祖先元素的定位偏移量之和 |
|
positionedOffset( element )
| 返回一个数组
[left, top]
,包含元素及其祖先元素到第一个具有绝对或相对位置的祖先元素的定位偏移量之和 |
|
offsetParent( element )
| 返回元素最近的具有非静态位置样式的祖先元素 |
|
within( element , x , y )
| 测试给定的点坐标
x
和
y
是否在元素的边界矩形内 |
|
withinIncludingScrolloffsets( element , x , y )
| 测试给定的点坐标
x
和
y
是否在元素的边界矩形内,考虑滚动偏移量 |
|
overlap( mode , element )
|
mode
应为
vertical
或
horizontal
。在调用此方法之前需要先调用
within()
。此方法将返回一个介于0.0和1.0之间的小数,表示坐标在元素上重叠的比例 |
|
page( element )
| 返回一个数组
[left, top]
,包含元素相对于视口的偏移量 |
|
clone( source , target )
| 将元素
target
的大小和位置调整为与
source
相同 |
|
absolutize( element )
| 将元素的位置样式设置为绝对,并保留其位置和大小 |
|
relativize( element )
| 将元素的位置样式设置为相对,并保留其位置和大小 |
以下是使用示例:
// 调整滚动偏移量
Position.prepare();
// 获取元素的滚动偏移量
var offset = Position.realOffset($('target'));
// 测试点是否在元素内
var isWithin = Position.within($('target'), 100, 100);
// 克隆元素位置
Position.clone($('source'), $('target'));
8. 表单观察者
表单观察者用于监测元素属性的变化,主要有以下几种类型。
8.1 抽象定时观察者
Abstract.TimedObserver
类用作其他监测元素属性变化的类的基类。
| 属性/方法 | 描述 |
| ---- | ---- |
|
initialize( element , frequency , callback )
| 创建一个对象,每
frequency
秒监测一次
element
,当元素发生变化时调用
callback
|
|
element
| 被监测的元素对象 |
|
frequency
| 检查之间的间隔(以秒为单位) |
|
callback
| 每当元素发生变化时调用的函数,符合
Function ( Object , String )
格式,将接收元素对象和新值 |
|
lastValue
| 元素中最后一次验证的值的字符串 |
8.2 表单元素观察者
Form.Element.Observer
是
Abstract.TimedObserver
的实现,用于监测表单输入元素的值。当要监测的元素没有暴露报告值变化的事件时使用此类。
// 监测表单元素值的变化
var observer = new Form.Element.Observer('inputId', 2, function(element, value) {
console.log('Value changed to: ' + value);
});
8.3 表单观察者
Form.Observer
是
Abstract.TimedObserver
的实现,用于监测表单中任何输入元素的任何变化。当要监测的表单包含没有暴露报告值变化事件的元素时使用此类。
// 监测表单数据的变化
var formObserver = new Form.Observer('formId', 3, function(form, value) {
console.log('Form data changed: ' + value);
});
8.4 抽象事件观察者
Abstract.EventObserver
类用作其他在元素发生值变化事件时执行回调函数的类的基类。多个观察者可以绑定到同一个元素,回调函数将按分配给元素的顺序执行。触发事件对于单选按钮和复选框是
onclick
,对于文本框和列表框/下拉框通常是
onchange
。
| 属性/方法 | 描述 |
| ---- | ---- |
|
initialize( element , callback )
| 创建一个对象,监测
element
,当事件发生时调用
callback
|
|
element
| 被监测的元素对象 |
|
callback
| 每当元素发生变化时调用的函数,符合
Function ( Object , String )
格式,将接收元素对象和新值 |
|
lastValue
| 元素中最后一次验证的值的字符串 |
8.5 表单元素事件观察者和表单事件观察者
Form.Element.EventObserver
和
Form.EventObserver
分别用于监测表单元素和表单的数据变化,利用元素的事件来检测值的变化。如果表单包含没有暴露任何报告变化事件的元素,则使用
Form.Observer
。
// 表单元素事件观察者
var elementEventObserver = new Form.Element.EventObserver('inputId', function(element, value) {
console.log('Element value changed: ' + value);
});
// 表单事件观察者
var formEventObserver = new Form.EventObserver('formId', function(form, value) {
console.log('Form data changed via event: ' + value);
});
下面是一个mermaid流程图,展示表单观察者的工作流程:
graph LR
A[创建观察者对象] --> B{选择观察者类型}
B -- 表单元素观察者 --> C[监测表单元素值变化]
B -- 表单观察者 --> D[监测表单数据变化]
B -- 表单元素事件观察者 --> E[利用事件监测表单元素值变化]
B -- 表单事件观察者 --> F[利用事件监测表单数据变化]
C --> G[值变化时调用回调]
D --> G
E --> G
F --> G
综上所述,通过这些丰富的DOM操作方法和类,开发者可以方便地对页面元素进行各种操作,包括元素的选择、样式修改、内容插入、定位以及表单数据的监测等,大大提高了开发效率和页面交互性。
超级会员免费看
34万+

被折叠的 条评论
为什么被折叠?



