美文网首页前端之旅前端转载的~es5
前端工程师之DOM编程艺术(持续更新)

前端工程师之DOM编程艺术(持续更新)

作者: 7091a52ac9e5 | 来源:发表于2016-03-06 13:46 被阅读561次

    @(书籍阅读)[网易云课堂|DOM]

    DOM编程艺术

    网易前端微专业之《DOM编程艺术》笔记,持续更新;

    • 更新事件相关操作(20160306)
    • 剩余内容(20160310)

    DOM树

    • Document Object Model(文档对象模式);
      • 用对象的方式来描述对应的模型;
    • 一系列API规范;增加删除节点等等;
    • DOM Core
    • DOM HTML
    • DOM Style
    • DOM Event

    HTML的对象的表示;

    节点树

    节点遍历

    node.parentNode
    node.firstChild
    node.lastChild
    node.previousSibling
    node.nextSibling
    

    节点类型

    //最常用
    ELEMENT_NODE
    TEXT_NODE
    
    元素遍历
    p.firstElementChild
    p.lastElementChild
    em.nextElementSibling
    em.previousElementSibling
    

    节点操作

    • 获取节点
      • 父子关系
        • parentNode
        • firstChild/lashChild/childNodes
        • childNodes/chileren
      • 兄弟关系
        • previousSibling/nextSibling
        • previousElementSibling/nextElementSibling
      • 通过已获取节点(关系)来获取节点可维护性非常差,位置变化就会出问题;
      • 如何通过接口来获取节点?:
        • id是节点的唯一标示
        • getElementById
          • element = document.getElementByid(id);
          • 获取文档中id为‘id’的元素;
        • getElementsByTagName
          • collection = element.getElementsByTagName(tagName),元素下面的选择,可以通过下标来获取指定集合中的元素[2];
            • 获取的值是动态的(活的),后续的操作会影响它的内容;
            • tagname为*可以获取该元素下所有的节点;
        • getElementsByClassName
          • collection = element.getElementsByClassName(className);
          • className可以传入用空格分割的多个className;(ie 6 ,7 ,8 不支持这个属性);
          • 特性侦测:如果支持则直接返回,优先使用W3C规范,之后再用别的方法选择;
        • querySelector/All
          • list=element.querySelector/All(selector);
          • Selector:第一个;
          • All:每一个
          • list不是动态的,一旦获取就不会变化了;
          • IE6,7不支持,IE8部分支持
    querySelector/All支持情况
    • 创建节点
      • element=document.createElement(tagName);
    • 修改节点
      • textContent:文本及其后代节点的文本内容;
        • element.textContent;ie9-不支持;
      • element.innerText:节点及其后代节点中的文本内容,不是w3c规范,ff不支持;
    • 插入节点
      • appendChild
        • var achild=element.appendChild(achild);
      • insertBefore
        • var achild = element.insertBefore(achild,referenceChild);
    • 删除节点
      • child = element.removeChild(child);
    • innerHTML
      • 节点的HTML内容
      • 重新设置了整个ul,原来的节点都没有了,原来节点上面的状态样式都被清理掉了;
      • 低版本ie上会内存泄露
      • 有一定的安全问题;
      • 不检查里面的内容,对用户产生的内容存在较大的风险;
      • 仅仅建议用于新的节点,且是用户不可控的内容,至少需要不允许加入标签;

    属性操作

    property accessor(属性访问器)

    读取属性

    input.className;
    input["id"];

    写属性

    input.value='www.baidu.com'

    类型(通过属性访问符会自动转换)
    • string
    • number
    • Boolean,只要属性出现就是true;
    • function(onclick)
    特点

    -通用性差(名字异常)
    -扩展性差
    但是是一个实用对象,会预先转换;

    getAttribute/setAttribute

    var attribute = element.getAttribute(attributeName);
    input.getAttribute(class);字符串不存在名字冲突
    input.setAttribute(name,value);
    input.setAttribute("disabled","");设置为空则为false;

    类型:
    • 属性的字符串
    特点:
    • 通用性好
    • 不是实用对象;

    dataset(自定义属性)

    • HTMLElement.dataset
    • data-"属性集"
    • 用途:元素上保存数据
    事件传输流程

    样式操作

    页面换肤:就是一下子改变很多元素的样式;

    • link : element.sheet;
    • element.style;
    • document.styleSheet;
    • element.sheet.cssRules[1].style
      • 键值对可以通过属性名获取属性值
      • selectorText
      • CSSStyleDeclaration;

    更新样式element.style

    element.style.borderColor = 'red';

    问题
    • 更新一个属性需要一条语句
    • 不是我们熟悉的CSS
      推荐使用:element.style.cssText = 'border-color:red;'
      但是上述两种方法:样式混在逻辑中;更好的方法是更新class;
    更新class;
    换肤(一次性更新很多元素的样式)

    更换样式表;
    link元素也可以添加id,选中,然后更改href;

    获取样式

    element.style

    对应的是元素的内嵌的样式,通过这种方式不能获取外联的样式;

    window.getComputedStyle()

    var style = window.getComputerStyle(element[,pseudoElt]);
    获取到的是一个只读属性不能修改;
    包含属性名和值的键值对,几乎包含所有属性;
    ie9以下不支持;

    CSS DOM overview

    document.styleSheets~StyleSheetList
    .link.sheet
    .style.sheet

    事件

    什么是DOM事件?
    • 点击一个DOM元素
    • 键盘按下
    • 输入内容
    • 输入完成
    • 。。。

    事件流

    capture phase:
    从顶端往下;
    target phase:
    事件触发过程;
    bubble phase;
    当前节点的父节点开始冒泡到顶端的window对象;

    事件注册

    eventTarget.addEventListener(type,listener,[useCaptaure])模式捕获;

    取消时间注册

    eventTarget.removeEventListener(type,listener[,useCapture])
    另一种方法:eventTarget.onClick="null";

    时间触发

    eventTarget.dispatchEvent(type);
    事件注册与取消

    • attachEvent/detachEvent
      时间触发
    • fireEvent(e)
    • no capture 没有捕获阶段
      浏览器兼容性

    事件对象

    当事件被触发时,所包含的状态和信息;

    时间对象的属性和方法:

    属性:

    • type
    • target(srcElement)
    • currentTarget
      方法:
    • stopPropagation
    • preventDefault
    • stopImmediatePropagation
    阻止事件传播
    • event.stopPropagation()(W3C),阻止事件冒泡
    • event.cancelBubble = true(IE)
    • event.stopImmediatePropagation()(W3C)
      • 阻止时间传播
      • 阻止当前节点的后续事件的发生
    默认行为

    Event.preventDefault():阻止默认行为(W3C)
    Event.returnValue=false(IE)

    事件分类

    事件分类:
    DOM事件分类及继承关系;鼠标事件类型、鼠标事件对象、鼠标事件举例;键盘、输入、焦点事件类型、事件对象、事件举例;其他常用事件介绍与举例;

    Event:load,unload,error,select,abort;
    UIEvent:resize,scroll;
    FocusEvent:blur,focus,focusin,focusout;
    InputEvent:beforeinput,input;
    keyboardEvent:keydown,keyup;
    MouseEvent:click,dbclick,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup;
    WheelEvent:wheel;

    事件分类
    Event
    Event事件
    window
    • load
    • unload:比如说跳转前
    • error
    • abort
    Image
    • load
    • error onerror:设置一个默认图片;
    • abort
    UIEvent
    UIEvent

    div里冒泡为yes,document上处理时冒泡为false;

    MouseEvent

    mouseover和mouseenter:
    mouseenter:进入个元素才会触发,忽略子对象;

    MouseEvent对象

    属性:

    • clientX,clientY;
    • screenX,screenY;(见下图)
    • ctrlKey,shiftKey,altKey,metaKey:是否按下某个键
    • button(0,1,2):分别代表鼠标左键,中键,右键;
    screenX坐标系
    MouseEvent顺序
    • 从元素A上方移过
    • mousemove->mouseover(A)->mouseenter(A)->mousemove(A)->mouseout(A)-mouseleave(A)
    • 点击元素
      -mousedown->[mousemove]->mouseup->click
    WheelEvent
    WheelEvent
    属性
    • deltaMode
    • deltaX
    • deltaY
    • deltaZ
    FocusEvent
    FocusEvent
    属性:
    • relatedTarget(失去焦点的元素/获取焦点的元素)
    InputEvent
    InputEvent
    先会触发beforeInputEvent
    input:输入过程会不断触发;
    keyboardEvent
    keyboardEvent
    属性:
    • key:字符串
    • code:字符串
    • ctrlKey,shiftKey,altKey,metaKey
    • repeat:按下去不动,持续触发

    事件代理

    将事件注册到元素的父元素上

    数据通信

    请求报文
    get
    响应报文

    常用HTTP方法:
    常用HTTP方法
    URL构成
    URL构成
    HTTP版本
    HTTP版本
    常见HTTP状态码
    常见HTTP状态码

    Ajax

    Ajax通信流程
    open()方法

    xhr.open(method,url[,async=true]);
    xhr.setRequestHeader(header,value);
    xhr.send([data=null]);
    请求参数序列化

    同源策略

    两个页面用了相同的协议(protocol),端口(port)和主机(host),那么两个页面就属于同一个源(origin);

    跨域资源访问

    W3C定义了CORS(Cross-Origin Resource Sharing:跨域资源共享);
    现代浏览器已经实现了CORS标准

    CORS

    其它跨域技术

    • Frame代理
    • JSONP
    • Comet
    • WebSocket等
    Frame代理
    Frame代理
    JSONP

    填充式JSON
    <script>可以实现跨域

    数据存储

    服务器端设置
    服务器端设置 作用域 作用路径
    读取
    function setCookie (name, value, expires, path, domain, secure) {
        var cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
        if (expires)
            cookie += '; expires=' + expires.toGMTString();
        if (path)
            cookie += '; path=' + path;
        if (domain)
            cookie += '; domain=' + domain;
        if (secure)
            cookie += '; secure=' + secure;
        document.cookie = cookie;
    }
    
    删除
    function removeCookie (name, path, domain) {
        document.cookie = name + '='
        + '; path=' + path
        + '; domain=' + domain
        + '; max-age=0';
    }
    
    缺陷
    • 流量代价(满足作用域和作用路径都会带着)
    • 安全性问题(明文传输)
    • 大小限制4kb
    cookie的作用:
    一定程度上弥补了http无状态协议对交互式web应用的影响,它可以使用客户端存储部分信息,维护用户和服务器会话中的状态。
    

    storage

    • localeStorage(永久)
    • sessionStorage
    sessionStorage
    • 大部分都在5MB左右;
    • 对内存造成不小的压力;
    • 可以当做JS对象
    读取:
    • localStorage.name
      添加/修改
    • localStorage.name="NetEase";(到目前为止存储类型只支持字符串)
      删除
    • delete localStorage.name
    API

    -获取键值对数量
    -localStorage.length
    读取

    • localStorage.getItem("name").localStorage.key(i)
      添加/修改
      -localStorage.setItem("name","NetEase")
      删除对应键值
    • localStorage.removeItem("name")
      删除所有数据
      -localStorage.clear()

    视频和音频

    多媒体和图形编程

    <audio><video>

    canPlayType();

    检查是否支持某种格式(Audio);

    <audio><video>除了界面上显示不一样,他们大部分的属性和方法是一样的
    Web Audio API

    音频:
    视频:
    多媒体相关事键表:
    W3C官方定义:
    mozilla官方教程:
    第三方教程:

    Canvas

    canvas:不建议用css指定宽高;
    ctx.globalCompositionOperation

    ctx.globalCompositionOperation

    基本绘图步骤

    基本绘图的步骤
    市面上常见的基于Canvas的引擎

    1. Laro:
    是一个基于html5 canvas的用于平面2d或者2.5d游戏制作的轻量级游戏引擎
    2. X-Canvas:
    一款跨平台的HTML5游戏引擎,提供手机游戏开发的完整解决方案。包含了加速引擎,游戏框架,物理引擎
    3. CutJS:
    一款专门用于跨平台游戏开发的开源2D HTML5渲染引擎,轻量级、快速、可交互
    4. cocos2djs:
    一个游戏框架,api广泛
    5. Phaser:
    一款专门用于桌面及移动HTML5 2D游戏开发的开源免费框架,提供JavaScript和TypeScript双重支持
    Mozilla官方教程:

    BOM

    JS包含三部分:

    • ECMAScript
    • DOM
    • BOM

    属性

    • navigator:浏览器信息;platform,userAgent;
    • location:浏览器定位和导航;href,修改可以进行浏览器跳转
    • assign(url),载入新的url,记录浏览历史
    • replace(url):不刷新浏览历史
    • reload(url):对浏览历史没影响
    • history:
      • back():正整数
      • forward():正整数
      • go():整数
      • screen:屏幕信息:avai:可用属性

    方法

    三种对话框
    • alert
    • confirm
    • prompt
      都会阻塞页面进程
    开,关新窗口

    var w = window.open();
    w.close();

    window事件
    • load:文档和所有图片加载完毕;
    • unload:离开当前文档
    • beforeunload:和unload
    • resize:拖动改变浏览器窗口大小时
    • scroll:拖动滚动浏览器

    表单操作

    步骤

    1. 构建表单
    2. 服务器处理
    3. 配置表单
    构建表单
    • form
    • label
    • fieldset
    • button
    • legend
    • input:使用required,必填
    学习内容
    • 元素
      • form
        • autocomplete:on off(之前输入历史是否被提示)
        • elements
          • 该元素子孙表单空间(除图片按钮(input type-image))
          • 归属于该表单的表单控件(除图片按钮)
          • 是一个动态节点集合
        • length 等价于 elements.length(元素个数)
        • 取得元素
          • testForm.elements[0]
          • testForm.element['a']:动态
          • testForm[0]
          • testForm['a']:静态
          • form[name]
            • 返回id或name为指定名称的表单控件(除图片按钮)
            • 如果结果为空,则返回id为指定名称的img元素
            • 如果有多个同名元素,则返回这些元素的动态节点集合
            • 一旦用指定名称取过该元素,就算更改其名称仍然可以通过原来名称找到该元素
        • reset()
          • 可重置元素:input,keygen,output,select,textarea
          • 触发表单reset事件,阻止该事件的默认行为可取消重置
          • 元素重置时不再触发元素上的change和input事件
        • submit()
        • checkValidity()
      • label
        • for:将标签指定到元素
        • htmlFor
          • 关联表单控件激活行为
          • 可关联元素:button,input(除hidden),keygen,meter,output,progress,select,textarea
          • label 的for 和input的id要一致(不同形状的文件上传)
        • control
          • 如果指定了for属性,则为该for属性对象id的可关联属性
          • 如果没有指定for属性,则为第一个子孙可关联元素
        • form
          • 关联归属表单
          • 可关联元素:button,fieldset,input,keygen,label,object,output,select,textarea
          • 只读属性,不可在程序中修改
            label.setAttribute('form','newForm')
        • input
          • type
            • 空间外观
            • 数据类型
            • 默认为text
            • 本地图片预览
              • onchange
              • accept:指定了选择的类型:audio/*,
              • multiple
              • files
        • select
          • optgroup
            • disabled
            • label
          • option
          • name
          • value:选中选项的value值
          • multiple:控制多选
          • options:选项集合(动态)
          • selectedOptions(选中的集合)
          • selectedIndex(选中的序号)
          • add(element[,before]):添加
          • remove([index]):移除
          • 创建选项
            • document.createElement
            • new Option()
          • 添加选项
            • insertBefore
            • select.add
          • 删除选项
            • removeChild
            • select.remove
          • textarea
            • name
            • value
            • select()
            • selectionStart
            • selectionEnd
            • selectionDirection
            • selectionEnd
            • selectionDirection
            • setSelectionRange(start,end[,direction])
            • setRangeText(replace[,start,end[,mode]])
          • fieldset,button,keygen,output,progress,meter
    <form id=test>
    <input name="a"/>
    <input name="b"/>
    </form>
    
    • 验证
      • 验证元素
        • 可验证元素:button,input,select,textarea
        • 以下情况不做验证:
          • input&&type是hidden,reset,button
          • button&&type是reset,button
          • input/textarea&&readonly
          • 作为datalist的子孙节点
          • disabled
      • element.
        • willValidate:是否被验证
        • checkValidity():直接验证某元素
        • validity:存储验证结果
        • validationMessage:显示验证异常信息
        • setCustomValidity(message):自定义验证错误信息
      • validity
    validity

    - 自定义异常
    - oninvalid
    - setCustomValidity
    - 禁止验证
    - novalidate
    - 利用form元素的novalidate属性,它可以关闭整个表单验证。(禁止当前表单内的所有可验证元素的验证)
    利用input元素或submit元素的formnovalidate属性,此属性可以让表单验证对单个元素失效。(禁止单个指定的可验证元素的验证)

    • 提交
      • 隐式提交:敲回车
        • 如:聚集在输入框时按回车提交表单
        • 满足以下任一条件:
          • 表单有非禁用提交按钮
          • 没有提交按钮时,不超过一个类型为text,search,url,email等
      • 提交过程:
        • 根据表单enctype指定的值构建要提交的数据结构
        • 使用method指定的方式发送数据到action指定的目标
      • 构建提交数据
        • 从可提交元素中提取数据组装成指定的数据结构的过程;
        • 可提交元素:button,input,keygen,object,select,textarea
      • 编码方式(enctype)
        • application/x-www-form-urlendcode
        • multipart:ifc2388字节流
        • text/plain:给人阅读
      • 特殊案例
        • name =“isindex”&&type=”text
          • 编码方式为application
          • 作为表单的第一个提交元素
          • 提交时只发送value值,不包含name
        • name=“charset”&&type="hidden"
          • 没有设置value值
          • 提交时value自动用当前字符集填充
      • submit()
        • 提交表单form.submit()
      • onsubmit()
        • 表单提交事件
        • 提交之前的数据验证
        • 阻止事件的默认行为可取消表单提交
    • 无刷新表单提交
      • form
      • target
      • iframe
    <!Doctype html>
    <html lang="en">
        <head>
        <meta charset="utf-8">
        <title>利用iframe实现表单的无刷新提交</title>
        </head>
        <body>
            <form target="formtarget" method="post">
                <input type="text" name="username">
                <input type="password" name="password">
                <input type="submit">
            </form>              
            <iframe name="formtarget"  style="display:none"></iframe>
            <div id='div1'></div>
                        
            <script type="text/javascript">
                var enventUtil={
                    addHandler:function(elem,type,handler){
                        if(elem.addEventListener){
                            elem.addEventListener(type,handler,false);
                        }else if(elem.attachEvent){
                            elem.attachEvent('on'+type,handler);
                        }else{
                            elem['on'+type]=handler;
                        }
                    }
                }
                var oFrame=document.getElementsByTagName('iframe');
                var oDiv=document.getElementById('div1');
                enventUtil.addHandler(oFrame,'load',function(){
                    var frameDocument=oFrame.contentDocument || oFrame.contentwindow.document;
                    if(frameDocument){
                        oDiv.innerHTML=frameDocument.body.innerHTML;
                    }
                })
            </script>
        </body>
    </html>
    

    表单应用

    列表操作

    形式

    • 图片
    • 信息

    编程方式

    • 面向视图
    • 面向数据

    相关文章

      网友评论

        本文标题:前端工程师之DOM编程艺术(持续更新)

        本文链接:https://www.haomeiwen.com/subject/sxjakttx.html