[关闭]
@15013890200 2018-09-13T19:31:02.000000Z 字数 5767 阅读 650

再读javascript(五)

原生javascript

上接再读javascript(四)
本章包含表单脚本错误处理ajax高级技巧(很难,以后再研究)可维护性和xingn新兴的API

1、表单提交

在触发表单提交操作时,可以利用event.preventDefault()阻止表单提交。(当表单验证未通过时)
在某些严禁重复提交操作时,可以设置按钮disable属性或者其他方法禁用提交。
novalidate 禁用表单验证
设置autocomplete = 'off'可以关闭烦人的自动补全功能

2、表单控件

  • form.elements 属性可以获取表单中所有节点
  • input:size属性可以指定文本框能够显示的字符数
  • 通过指定pattern属性达到控制输入模式
  • textarea:rows和cols属性设定行数和列数
    1. //文本框只输入数值控制
    2. var charCode = event.charCode;
    3. if(!/\d/.test(String.fromCharCode(charCode)) && charCode > && !event.ctrlKey){
    4. event.preventDefault();
    5. }

3、跨文档消息传递

不同域的页面间传递消息。核心是postMessage()方法。
postMessage接收两个参数,一条消息和接收方来自哪个域。主要运用场景是当前页面的iframe元素或者是由当前页面弹出的窗口。
onmessage 接收postMessage传送的消息。

4、拖放事件

dragstart事件:按下鼠标并开始移动时触发。
drag事件:dragstart事件后,会随即触发drag事件,元素拖动期间会持续触发该事件
dragend事件:拖动停止时触发
当元素被拖动到一个有效的放置目标时,会触发下列事件:

dragenter事件、dragover事件、dragleave事件或者drop事件

  • dataTransfer对象

    getData()和setData()方法

  • 可拖动

    draggable属性,表示元素是否可以被拖动


5、try-catch-finally语句

  • 正常情况下,catch和finally存在一个即可。但是为了兼容ie8之前的版本,finally必须在catch子句存在时才执行。因此尽量选择catch语句,选择finally子句时,带上个空的catch子句。
  • 只要代码包含finally子句,那么无论try还是catch语句块中的return语句都会被忽略。

6、ajax

  • XMLHttpRequest对象
  1. //跨浏览器创建一个XMLHTTPRequest对象
  2. function createXHR() {
  3. if(typeof XMLHttpRequest != 'undefined'){
  4. //一般都会返回这个
  5. return new XMLHttpRequest();
  6. }
  7. else if(typeof ActiveXObject != 'undefined'){
  8. //兼容ie7以下
  9. if (typeof arguments.callee.activeXString != "string"){
  10. var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len;
  11. for(i = 0,len = versions.length; i < len; i++){
  12. try{
  13. new ActiveXObject(versions[i]);
  14. arguments.callee.activeXString = versions[i];
  15. break;
  16. }
  17. catch(e){
  18. }
  19. }
  20. }
  21. return new ActiveXObject(arguments.callee.activeXString);
  22. }
  23. else {
  24. throw new Error("No XHR object available.");
  25. }
  26. }
  • xhr的用法
  1. let xhr = createXHR();
  2. xhr.onreadystatechange = function () {
  3. if(xhr.readyState == 4){
  4. if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
  5. console.log('success');
  6. }
  7. else {
  8. console.log('false');
  9. }
  10. }
  11. };
  12. xhr.open('method','url','boolean');
  13. xhr.setRequestHeader('MyHeader','MyValue');//可选,但是一定要放在open之后,send之前
  14. xhr.send(null);
  • get请求

    当需要在链接添加参数时,?后面的字符串中的每个参数的名称和值都必须使用encodeURIComponent()进行编码

  • post请求

    Content-Type头部信息

  • FormData可以不必显示的设置请求头部为表单数据。xhr对象能够识别传入的数据类型是formdata的实例,并配置适当的头部信息。

    var data = new FormData();
    data.append('name','wj');

  • timeout给请求设置超时时间

    xhr.timeout = 2000; // 请求超时设置为1秒钟
    xhr.ontimeout = function(){
    console.log("request is timeout") //设置请求超时处理程序
    }

  • 进度事件:loadstart、progress、error、abort、load、loadend

    load事件,浏览器接收到服务器的响应,不管状态如何,都会触发load事件。这就意味着你必须检验status属性,才能确定是否真的已经可用。

  1. xhr.onload = function(){
  2. if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
  3. console.log('yes');
  4. }
  5. else{
  6. console.log('no');
  7. }
  8. }

progress事件,在浏览器接收新数据期间周期性地触发。onprogress事件处理程序接收一个event对象,其target属性是XHR对象,但包含着额外三个属性:lengthComputable(表示进度性息是否可用的布尔值),position(表示已经接收的字节数),totalSize(表示根据Content-Length响应头部确定的预期字节数)

  1. xhr.onprogress = function(event){
  2. if(event.lengthComputable){
  3. console.log(event.position,event.totalSize);
  4. }
  5. }
  • 跨源资源共享: 出于跨域安全策略,默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。

    CORS(跨源资源共享):自定义HTTP头部让浏览器与服务器进行沟通。
    在发送跨域ajax请求时需要额外指定Origin头部,其中包含请求页面的原信息(协议、域名和端口)

  • 跨浏览器的CORS

  1. function createCORS(method,url){
  2. var xhr = new XMLHttpRequest();
  3. if("withCredentials" in xhr){
  4. xhr.open(method,url,true);
  5. }
  6. else if(typeof XDomainRequest != "undefined"){
  7. xhr = new XDomainRequest();
  8. xhr.open(method,url);
  9. }
  10. else{
  11. xhr = null;
  12. }
  13. return xhr;
  14. }
  15. var request = createCORS('get','http://...');
  16. if(request){
  17. request.onload = function(){
  18. //...
  19. }
  20. request.send();
  21. }


  • 其他跨域技术

    • 图像ping。一个网页可以从任何网页中加载图像,不用担心跨域。利用他们onload和onerror事件处理程序是否接受带响应,缺点:只能发送get请求;无法访问服务器的响应文本。
    • JSONP
  1. function handleResponse(response){
  2. //do something ...
  3. }
  4. var script = document.createElement('script');
  5. script.src = "htt[://baidu.com?callback=handleResponse";
  6. document.body.insertBefore(script,document.body.firstChild);

Comet:服务器想页面推送数据。
Web Sockets:在一个单独的持久连接上提供双工、双向通信。


7、函数柯里化

8、防篡改

  • 不可扩展(不可新增属性和方法,但是可以删除和修改)

    设置obj对象不可扩展:Object.preventExtensions(obj)
    检测:Object.isExtensible(obj)

  • 密封(不可新增、删除、修改属性和方法)

    设置:Object.seal(obj)
    检测:Object.isSealed(obj)

  • 冻结()

    设置:Object.freeze(obj)
    检测:Object.isFrozen(obj)

冻结或密封javascript库中的核心对象,可以避免人为意外或刻意的修改

9、重复的定时器

  1. setTimeout(function(){
  2. //...
  3. setTimeout(arguments.callee,50);
  4. },50);

10、拖放(很有意思)

11、数据存储


  • cookie:存储在特定域名下,在发送请求时,会携带相关信息

    cookie名不区分大小写;cookie存储的值必须被URL编码;可以指定过期时间
    document.cookie 可以访问和设置cookie

12、可维护性

  • 代码缩进:一般用固定空格代替tab符。原因:tab符不同文本编辑器显示有差异
  • 减少全局变量:变量和方法尽可能定义在一个全局变量内
  • 常量:在文件头部定义一个全局变量Constans,其他常量大写命名,定义为其相应属性
  • 重复值:经常遇到重复用到某个值,可以抽取为一个常量
  • urls:推荐用一个公共的地方存放所有的url

13、性能

  • 避免全局查找:将在一个函数中会用到多次的全局对象存储为局部变量总是没错的。
  • 避免使用with语句
  • 避免不必要的属性查找:js访问数组元素和煎蛋变量的时间复杂度都是O(1),访问对象属性的时间复杂度是O(n),因此要减少不必要的属性查找。
  • 优化循环
  • switch语句优于if-else
  • 声明多个变量用,分割,避免多次声明
  • 声明数组或对象,字面量方法优于构造函数方法
  • 优化dom交互

    • 避免现场更新(插入或者移除、更新dom)
    • 对于大的dom更改,使用innerHTML要优于标准dom创建方法(createElement)
  • 利用事件冒泡原理来捕获相应操作优于添加多个事件代理


14、新兴的API

  • 页面显示/隐藏api

    • 利用document.hidden 属性可以判断页面是否不可见。
    • document.onvisibilitychange() 事件可以在页面显示/隐藏时触发
  • 地理定位API

    • 可以通过 navigator.geolocation 对象访问地理信息。
    • navigator.geolocation.getCurrentPosition 方法会触发请求用户共享地理定位信息的对话框。接受三个参数:1、成功回调函数;2、可选的失败回调函数;3、可选的选项对象。成功回调函数会接收到一个position对象
    • watchPosition() 方法可以跟踪用户的位置信息
  1. navigator.geolocation.getCurrentPosition(function){
  2. drawMapCenteredAt(position.coords.latitude,position.coords.longitude);
  3. },function(error){
  4. console.log(error.code + ' ' + error.message);
  5. },{
  6. enableHighAccuracy: true, //尽可能获取最精确的位置信息
  7. timeout: 5000, //等待位置信息的最长时间
  8. maximumAge: 2500 //距上一次取得坐标信息的有效时间
  9. });


  • File API

    • 获取文件中的基本信息: event.target.files ;获取的是文件信息列表。
    • FileReader类型及其方法如下:
      • readAsText(file,encoding):以纯文本形式读取文件,将读取到的文本保存在result属性中,参数二指定编码类型(可选)
      • readAsDataURL(file):读取文件并将文件以数据URI的形式保存在result属性中。
      • readAsBinaryString(file):读取文件并将一个字符串保存在result属性中。
      • readAsArrayBuffer(file):读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中
    • 由于读取过程是异步的,因此FileReader提供了三个事件:progress、error、load,分别表示是否读取了新数据、是否发生了错误、是否已经读完了整个文件。

    • 与xhr的progress事件相同,包含lengthComputable、loaded、total
  • File对象还支持一个slice方法支持读取部分数据

  • 对象URL,使用 window.URL.createObjectURL() 方法可以不必把文件内容读取到javascript中而直接使用。
  • event.dataTransfer.files 可以读取拖放的文件信息

15、使用XHR上传文件

  • 通过File API确实能够读取文件内容,然后将文件内容放到send方法中,再通过POST请求发送。服务器端接收到数据再把他们存放到另一个文件中。更好的做法是用表单提交的方式来上传文件。
  1. data = new FormData();
  2. files = event.target.files;
  3. for(var i = 0,len = files.length; i < len; i++){
  4. data.append(files[i])
  5. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注