1、前言
在之前的博客中,我们一直通过dom.byId
方法来获取dom
元素。但在实际开发过程中,单凭id
获取dom
元素是无法满足开发需求的,例如根据css
样式名称获取对应的dom
元素集合、获取某个div
下所有的超链接<a>
元素等。Dojo
中提供了dojo/query
模块,该模块可实现复杂情况下的dom
元素拾取,下面开始介绍。
2、基础查询器
dojo/query
模块提供了非常多灵活实用的方法来拾取dom
元素,基础的方法包括根据id
、class
、tag
获取dom
元素。
2.1、根据id获取dom元素
dojo/query
模块支持根据id
获取dom
元素。不过在写法上与dom.byId
有所不同,代码如下:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><h1 id="title">这是一个标题</h1><script>require(['dojo/query', 'dojo/domReady!'], function (query) {var title = query('#title')[0].innerHTML;console.log(title);});</script>
</body>
</html>
query
方法需要传入dom
元素的id
值,同时要加上一个#
符号。同时,query
方法返回的是一个数组,因此需要写为query('#id')[0]
的形式。运行结果如下所示:
这是一个标题
2.2、根据class获取dom元素
query
查询器允许根据css
名称获取dom
元素集合,代码如下:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><style>.one {color: red;}.two {color: blue;}</style><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><h1 class="one">这是标题1</h1><h1 class="two">这是标题2</h1><h1 class="one">这是标题3</h1><h1 class="two">这是标题4</h1><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// 查询class="one"的元素集合var titles = query('.one');titles.forEach(function (title) {console.log(title.innerHTML);})console.log('----------');// 查询class="two"的元素集合titles = query('.two');titles.forEach(function (title) {console.log(title.innerHTML);})});</script>
</body>
</html>
运行结果如下所示:
这是标题1
这是标题3
----------
这是标题2
这是标题4
2.3、根据tag标签获取dom元素
query
查询器允许根据tag
标签名称获取dom
元素集合,代码如下:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><h1>这是标题1</h1><h1>这是标题2</h1><h1>这是标题3</h1><h1>这是标题4</h1><script>require(['dojo/query', 'dojo/domReady!'], function (query) {var titles = query('h1');titles.forEach(function (title) {console.log(title.innerHTML);})});</script>
</body>
</html>
运行结果如下所示:
这是标题1
这是标题2
这是标题3
这是标题4
3、层次查询器
在实际业务中,根据各个dom
元素之间的层次关系查询也是常见操作。一般的层级关系包括祖先后代关系,父子关系、相邻兄弟关系。
3.1、祖先后代关系
dojo/query
模块支持根据祖先与后代的层级关系获取dom
元素。下面代码演示了获取body
下所有的div
和h1
标签:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div style="background-color: red;"><h1>这是标题1</h1><h1>这是标题2</h1></div><div style="background-color: yellow;"><h1>这是标题3</h1><h1>这是标题4</h1></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// 获取body下所有的divquery('body div').forEach(function (div) {console.log('背景色:' + div.style.backgroundColor);})console.log('--------');// 获取body下所有的h1query('body h1').forEach(function (title) {console.log(title.innerHTML);})});</script>
</body>
</html>
运行结果如下所示:
背景色:red
背景色:yellow
--------
这是标题1
这是标题2
这是标题3
这是标题4
3.2、父子关系
父子关系与祖先后代关系略有不同,祖先后代关系可以向下无限层级查询,而父子关系只能向下查询一级。例如body
与div
是父子关系,div
与h1
是父子关系,代码如下:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div style="background-color: red;"><h1>这是标题1</h1><h1>这是标题2</h1></div><div style="background-color: yellow;"><h1>这是标题3</h1><h1>这是标题4</h1></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// body与div为父子关系query('body>div').forEach(function (div) {console.log('背景色:' + div.style.backgroundColor);})console.log('--------');// div与h1为父子关系query('div>h1').forEach(function (title) {console.log(title.innerHTML);})console.log('--------');// body与h1不是父子关系,因此无法获取h1文本query('body>h1').forEach(function (title) {console.log(title.innerHTML);})});</script>
</body>
</html>
运行结果如下所示:
背景色:red
背景色:yellow
--------
这是标题1
这是标题2
这是标题3
这是标题4
--------
3.3、相邻兄弟关系
dojo/query
也支持相邻兄弟关系的查询。该关系指的是某个元素相邻的下一个dom
元素,在下面的代码中,box1
与box2
为相邻兄弟关系,box2
与box3
为相邻兄弟关系:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div id="box1" style="background-color: red;"></div><div id="box2" style="background-color: yellow;"></div><div id="box3" style="background-color: green;"></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// box1的相邻兄弟为box2query('#box1+div').forEach(function (div) {console.log('背景色:' + div.style.backgroundColor);})console.log('--------');// box2的相邻兄弟为box3query('#box2+div').forEach(function (div) {console.log('背景色:' + div.style.backgroundColor);})});</script>
</body>
</html>
运行结果如下所示:
背景色:yellow
--------
背景色:green
3.4、对层级关系做一定限制
在实际开发过程中,一个页面往往包含众多的的dom
元素,因此很多情况下我们只希望只在特定的dom
元素下执行层次查询。下面代码演示了在id="box1"
的div
内执行层次查询:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div id="box1"><h1>这是标题1</h1><h1>这是标题2</h1><p>这是段落1</p><p>这是段落2</p><div id="child1" style="background-color:red;"></div><div id="child2" style="background-color:blue;"></div></div><div id="box2"><h1>这是标题3</h1><h1>这是标题4</h1><p>这是段落3</p><p>这是段落4</p><div id="child3" style="background-color:red;"></div><div id="child4" style="background-color:blue;"></div></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// box1下执行祖先后代查询query('#box1 h1').forEach(function (item) {console.log(item.innerHTML);})console.log('--------');// box1下执行父子查询query('#box1>p').forEach(function (item) {console.log(item.innerHTML);})console.log('--------');// box1下执行相邻兄弟查询query('#box1 #child1+div').forEach(function (item) {console.log('背景色:' + item.style.backgroundColor);})});</script>
</body>
</html>
运行结果如下所示:
这是标题1
这是标题2
--------
这是段落1
这是段落2
--------
背景色:blue
4、属性查询器
在针对form
表单进行查询时,我们常常需要根据某些属性进行定位。
4.1、查询包含某个属性的表单元素
下面代码演示了查询包含type
属性的表单元素:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" name="userName" value="admin" /><input type="password" name="password" value="12345" /></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {query('input[type]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
admin
12345
4.2、查询等于特定属性值的表单元素
下面代码演示了查询type=text
和type=password
的表单元素:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" name="userName" value="admin" /><input type="password" name="password" value="12345" /></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {query('input[type=text]').forEach(function (item) {console.log(item.value);})query('input[type=password]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
admin
12345
4.3、查询以某属性值开头的表单元素
Dojo
中使用通配符^=
表示以某个值开头,下面代码演示了查询name
属性以user
和pass
开头的表单元素:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" name="userName" value="admin" /><input type="password" name="password" value="12345" /></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {query('input[name^=user]').forEach(function (item) {console.log(item.value);})query('input[name^=pass]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
admin
12345
4.4、查询以某属性值结尾的表单元素
Dojo
中使用通配符$=
表示以某个值结尾,下面代码演示了查询name
属性以Name
和word
结尾的表单元素:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" name="userName" value="admin" /><input type="password" name="password" value="12345" /></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {query('input[name$=Name]').forEach(function (item) {console.log(item.value);})query('input[name$=word]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
admin
12345
4.5、查询包含某属性值的表单元素
Dojo
中使用通配符*
表示包含某个值,下面代码演示了查询name
属性包含userN
和passw
的表单元素:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" name="userName" value="admin" /><input type="password" name="password" value="12345" /></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {query('input[name*=userN]').forEach(function (item) {console.log(item.value);})query('input[name*=passw]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
admin
12345
4.6、表单属性查询的一些代码
我在这里列举了一些Dojo
中的表单属性查询方法,代码如下:
<!DOCTYPE html>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /><title>demo</title><script src="http://localhost/arcgis_js_api/library/4.15/dojo/dojo.js"></script>
</head>
<body><div><input type="text" disabled value="123" /><input type="text" readonly="readonly" value="456" /></div><div><input type="radio" name="gender" value="男" checked />男<input type="radio" name="gender" value="女" />女</div><div><input type="checkbox" name="city" value="上海" checked />上海<input type="checkbox" name="city" value="杭州" checked />杭州<input type="checkbox" name="city" value="南京" />南京<input type="checkbox" name="city" value="合肥" />合肥</div><div><select id="fruit"><option value="橘子" selected="selected">橘子</option><option value="菠萝">菠萝</option><option value="西瓜">西瓜</option></select></div><script>require(['dojo/query', 'dojo/domReady!'], function (query) {// 查询不可用的文本框query('input[type=text]:disabled').forEach(function (item) {console.log(item.value);})// 查询只读的文本框query('input[type=text][readonly=readonly]').forEach(function (item) {console.log(item.value);})// 查询单选按钮radio选中的值query('input[name=gender]:checked').forEach(function (item) {console.log(item.value);})// 查询复选框checkbox选中的值query('input[name=city]:checked').forEach(function (item) {console.log(item.value);})// 查询下拉框select选中的值query('#fruit>option[selected=selected]').forEach(function (item) {console.log(item.value);})});</script>
</body>
</html>
运行结果如下所示:
123
456
男
上海
杭州
橘子
5、结语
本文主要介绍了Dojo
中的query
查询器,主要涉及到基础查询、层次查询、属性查询三块内容。在实际开发过程中,在合适的场景下选择合适的查询方式可以让你的开发工作事半功倍。