DOM 相关 - 事件机制

博客分类: 江河计划

DOM 相关 - 事件机制

算法

队列

class Queue {
    private items :any[] = [];
    enqueue(...items:any[]){
        this.items = this.items.concat(items);
    }
    dequeue():any{
        return this.items.shift();
    }
    front():any{
        return this.items[0];
    }
    isEmpty():boolean{
        return this.items.length === 1;
    }
    size():number{
        return this.items.length;
    }
    print(){
        console.log(this.items.toString());
    }
}

单链表

interface Node {
    element: any;
    next: any;
}

class LinkedList {
    private length:number = 0;
    private list:any = null;
    getNode(element:any):Node{
        return {
            element,
            next: null
        }
    }
    append(element:any){
        let node = this.getNode(element);
        if(!this.list){
            this.list = node;
        }else{
            let current = this.list;
            while(current.next){
                current = current.next;
            }
            current.next = node;
        }
        this.length++;
    }
    insert(position:number, element:any){
        let node = this.getNode(element),
            current = this.list;
        if(this.length >= position){
            if(position === 0){
                node.next = current;
                this.list = node;
            }else{
                let previous = null;
                for(let i=0; i<position; i++){
                    previous = current;
                    current = current.next;
                }
                previous.next = node;
                node.next = current;
            }
            this.length++;
        }else{
            this.append(element);
        }
    }
    removeAt(position:number){
        if(position === 0){
            this.list = this.list.next;
        }else{
            let previous = this.list;
            for(let i=0; i<position-1; i++){
                previous = previous.next;
            }
            let next = previous.next.next;
            previous.next = next;
        }
        this.length--;
    }
    remove(element:any){
        this.removeAt(this.indexOf(element));
    }
    indexOf(element:any):number{
        var index = 0,
            current = this.list;
        while(element !== current.element){
            index++;
            current = current.next;
        }
        return index;
    }
    isEmpty():boolean{
        return this.length === 0;
    }
    size():number{
        return this.length;
    }
    getHead():object{
        return this.list;
    }
    toString():string{
        let string = '',
            current = this.list;
        if(current){
            string += current.element;
            while(current.next){
                current = current.next;
                string += current.element;
            }
        }
        return string;
    }
    print(){
        console.log(this.toString());
    }
}

// 测试代码
var linkedList = new LinkedList();
linkedList.print();
linkedList.append(1);
linkedList.print();
linkedList.append(2);
linkedList.print();
linkedList.append(3);
linkedList.print();
linkedList.append(5);
linkedList.print();
linkedList.insert(3, 4);
linkedList.print();
console.log(linkedList.indexOf(4));
linkedList.remove(4);
linkedList.print();
linkedList.removeAt(3);
linkedList.print();
console.log(linkedList.size());
linkedList.getHead();

正则

匹配 16 进制:/#[0-9a-fA-F]{6}|[0-9a-fA-F]{3}/

事件机制

IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获。

事件流的三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

image

[1-4]是事件捕获阶段 [4-5]是处于目标阶段 [5-9]是事件冒泡阶段

各浏览器的事件触发及事件委托

IE只支持时间冒泡,不支持事件捕获,IE的事件流只有事件从发生的目标开始,沿着文档逐层向上冒泡到document为止,其他浏览器支持捕获也支持冒泡。很明显如果在捕获阶段触发的话,事件会被触发两次。在冒泡阶段捕获只会触发一次。

W3C事件模型中你可以选择是在捕获阶段还是冒泡阶段绑定事件处理函数,这是通过addEventListener()方法实现的,如果这个函数的最后一个参数是true,则在捕获阶段绑定函数,反之false,在冒泡阶段绑定函数。

element1.addEventListener('click',doSomething1,true)    // 捕获阶段触发
element2.addEventListener('click',doSomething2,false)    // 冒泡阶段触发

这种模型下,还可以把事件冒泡关掉。在回调函数doSomething中,可以得到一个目标事件对象参数,这里取值为event。可以使用e.stopPropagation(),关掉从这个事件之后的事件冒泡。还有个常用方法是e.preventDefault(),这个是阻止目标事件的默认事件的触发,比如<a>标签的跳转,<button>按钮的提交等。千万不要记混了。

IE事件模型中不支持事件捕获,所以也就不会有第三个参数,使用方法也变了。

element.attachEvent("onclick", doSomething);

IE事件模型也有阻止事件冒泡的方法window.event.cancelBubble = true;,也有阻止事件的默认事件的触发window.event.returnValue = false;

还有些事件本身就不会冒泡blur、focus、load、unload

event

属性/方法 说明
bubbles 表明事件是否冒泡
cancelable 表明是够可以取消事件的默认行为
currentTarget 其事件处理程序当前正在处理事件的哪个元素
defaultPrevented 是否已经调用 event.prevented()
detail 与时间相关的细节信息
eventPhase 调用事件处于哪个阶段 1:捕获,2:目标,3:冒泡
preventDefault() 取消事件的默认行为
stopImmediatePropagation() 取消事件的进一步捕获或冒泡,阻断任何事件处理程序被调用
stopPropagation() 取消事件的的捕获或者冒泡,不阻断事件处理程序被调用

事件类型

时间名 说明
load 当页面完全加载后
unload 当页面完全卸载之后
abort 用户停止加载时
error 发生了错误的时候
select 当用户选择文本框时
resize 当窗口大小发生变化的时候
scroll 当用户滚动带滚动条的元素时
鼠标事件  
click 点击事件
dbclick 双击
mousedown 按下鼠标
mouseenter 当鼠标滑入区域内时
mouseleave 当鼠标离开区域时触发
mousemove 当鼠标在区域内移动时触发
mouseover 当鼠标滑入区域内时触发
mouseout 当鼠标离开区域时触发
mouseup 当鼠标放开时触发
键盘事件  
keydown 键盘按下
keypress 按住的过程中
keyup 键盘那件释放时触发
设备事件  
orientationchange 屏幕发生旋转时触发
deviceorientation 陀螺仪
移动手点  
touchstart 手指触摸屏幕时触发
touchmove 手指在屏幕上滑动时连续触发
touchend 当手指离开时触发
touchcancel 当系统停止追踪时触发
手势  
gesturestart 当一个手指已经按照屏幕上,另一只手又触摸到屏幕了
gesturechange 当触摸屏幕的任何一个手指的位置发生变化时
gestureend 当任何一个手指离开时

事件顺序

touchstart -> mouseover -> mousemove -> mousedown -> mouseup -> click -> touchend