javascript之DOM操作
DOM操作
DOM是一个树形结构, 常用操作有:更新, 遍历, 添加, 删除
获取dom节点的方法:
document.getElementById()
document.getElementsByTagName()
document.getElementsByClassName() //CSS选择器
可以连续调用: var trs = document.getElementById('test-table').getElementsByTagName('tr');
使用selector语法:
querySelector()
querySelectorAll()
注意: 低版本的IE<8不支持querySelector和querySelectorAll。IE8仅有限支持。
根节点Document已经自动绑定为全局变量document。
严格地讲,我们这里的DOM节点是指Element,但是DOM节点实际上是Node,
在HTML中,Node包括Element、Comment、CDATA_SECTION等很多种,以及根节点Document类型,但是,绝大多数时候我们只关心Element.
更新DOM
直接修改节点的文本,方法有两种:
修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内容,还可以直接通过HTML片段修改DOM节点内部的子树.
注意: 在写入HTML。如果写入的字符串是通过网络拿到了,要注意对字符编码来避免XSS攻击。修改innerText或textContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签.
innerText不返回隐藏元素的文本,而textContent返回所有文本。另外注意IE<9不支持textContent。
DOM节点的style属性对应所有的CSS,可以直接获取或设置。
注意:CSS允许font-size这样的名称,但它并非JavaScript有效的属性名,需要在JavaScript中改写为驼峰式命名fontSize.
插入DOM
两个办法可以插入新的节点
- 使用appendChild,把一个子节点添加到父节点的最后一个子节点
- 使用insertBefore, 使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。
删除DOM
- 调用父节点的removeChild把当前节点删掉
注意:删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置
当遍历一个父节点的子节点并进行删除操作时,要注意,children属性是一个只读属性,并且它在子节点变化时会实时更新
删除多个节点时,要注意children属性时刻都在变化, 容易造成index溢出.
表单操作
HTML表单的输入控件主要有以下几种:
- 文本框,对应的,用于输入文本;
- 口令框,对应的,用于输入口令;
- 单选框,对应的,用于选择一项;
- 复选框,对应的,用于选择多项;
- 下拉框,对应的
- 隐藏文本,对应的,用户不可见,但表单提交时会把隐藏文本发送到服务器。
直接调用value获得对应的用户输入值, input.value; // '用户输入的值'
对于单选框和复选框,value属性返回的永远是HTML预设的值,要获得的实际是用户是否“勾上了”选项,应该用checked判断.
HTML5控件
HTML5新增了大量标准控件,常用的包括date、datetime、datetime-local、color等,它们都使用<input>
标签.
不支持HTML5的浏览器无法识别新的控件,会把它们当做type=”text”来显示。支持HTML5的浏览器将获得格式化的字符串
提交表单
第一种方式:通过<form>
元素的submit()方法提交一个表单, 这种方式的缺点是扰乱了浏览器对form的正常提交。
浏览器默认点击<button type="submit">
或用户在最后一个输入框按回车键时提交表单。
第二种方式:响应<form>
本身的onsubmit事件,在提交form时作修改.
出于安全考虑,提交表单时不传输明文口令,而是口令的MD5, 口令框的显示会突然从几个*
变成32个*
,(MD5有32个字符)
要想不改变用户的输入,可以利用<input type="hidden">
实现.
注意到id为md5-password的<input>
标记了name=”password”,而用户输入的id为input-password的<input>
没有name属性。
没有name属性的<input>
的数据不会被提交。
文件操作
在HTML表单中,可以上传文件的唯一控件就是<input type="file">
注意: 当一个表单包含<input type="file">
时,表单的enctype必须指定为multipart/form-data,method必须指定为post,
这样浏览器才能正确编码并以multipart/form-data格式发送表单的数据。
出于安全考虑,浏览器只允许用户点击<input type="file">
来选择本地文件,用JavaScript对<input type="file">
的value赋值是没有任何效果的。当用户选择了上传某个文件后,JavaScript也无法获得该文件的真实路径
File API
随着HTML5的普及,新增的File API允许JavaScript读取文件内容,获得更多的文件信息。
HTML5的File API提供了File和FileReader两个主要对象,可以获得文件信息并读取文件。
回调
浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行,
也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行.
在JavaScript中,执行多任务实际上都是异步调用.
AJAX
Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求。
通过检测window对象是否有XMLHttpRequest属性来确定浏览器是否支持标准的XMLHttpRequest,
不要根据浏览器的navigator.userAgent来检测浏览器是否支持某个JavaScript特性.
安全限制
由于浏览器的同源策略,默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致,
即域名,协议和端口号要一致.有的浏览器可能允许端口不同.
那是不是用JavaScript无法请求外域(就是其他网站)的URL了呢?方法还是有的,大概有这么几种:
一是: 通过Flash插件发送HTTP请求,这种方式可以绕过浏览器的安全限制,但必须安装Flash,并且跟Flash交互。不过Flash用起来麻烦,而且现在用得也越来越少了。
二是:通过在同源域名下架设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器,代理服务器再把结果返回,这样就遵守了浏览器的同源策略。这种方式麻烦之处在于需要服务器端额外做开发。
第三种方式称为JSONP,它有个限制,只能用GET请求,并且要求返回JavaScript。这种方式跨域实际上是利用了浏览器允许跨域引用JavaScript资源.JSONP通常以函数调用的形式返回
CORS(Cross-Origin Resource Sharing): 是HTML5规范定义的如何跨域访问资源
Origin表示本域,也就是浏览器当前页面的域。当JavaScript向外域(如sina.com)发起请求后,浏览器收到响应后,首先检查Access-Control-Allow-Origin是否包含本域,如果是,则此次跨域请求成功,如果不是,则请求失败,JavaScript将无法获取到响应的任何数据。
假设本域是my.com,外域是sina.com,只要响应头Access-Control-Allow-Origin为http://my.com
,或者是*
,本次请求就可以成功。
可见,跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin,决定权始终在对方手中。
promise
Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了.
Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。job1.then(job2).then(job3).catch(handleError);
,其中,job1、job2和job3都是Promise对象。
canvas
Canvas是HTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表、动画等。
没有Canvas的年代,绘图只能借助Flash插件实现,页面不得不用JavaScript和Flash进行交互。
有了Canvas,我们就再也不需要Flash了,直接使用JavaScript完成绘制。