DOM 相关 - BOM

博客分类: 江河计划

DOM 相关 - BOM

算法

单向链表

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) {
        const 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 current = this.list;
        let node = this.getNode(element);
        if (this.length > position && position >= 0) {
            if (position === 0) {
                node.next = current;
                this.list = node;
            } else {
                for (let i = 1; i < position; i++) {
                    current = current.next
                }
                node.next = current.next;
                current.next = node;
            }
            ++this.length
        } else {
            this.append(element);
        }
    }
    removeAt(position: number) {
        if (this.length > position && position >= 0) {
            if (position === 0) {
                this.list = this.list.next;
            } else {
                let current = this.list;
                for (let i = 1; i < position; i++) {
                    current = current.next;
                }
                current.next = current.next.next;
            }
            --this.length
        }
    }
    remove(element: any) {
        this.removeAt(this.indexOf(element))
    }
    indexOf(element: any): number {
        let index = -1;
        let current = this.list;
        for (let i = 0; i < this.length; i++) {
            if (current.element === element) {
                return i
            }
            current = current.next;
        }
        return -1
    }
    isEmpty(): boolean {
        return this.length === 0;
    }
    size(): number {
        return this.length;
    }
    getHead() {
        return this.list;
    }
    toString(): string {
        var string: 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();

双向链表

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

class LinkedList {
    private length: number = 0;
    private list: any = null;
    getNode(element: any): Node {
        return {
            element,
            next: null,
            prev: null
        }
    }
    append(element: any) {
        const node = this.getNode(element);
        if (!this.list) {
            this.list = node;
        } else {
            let current = this.list
            while (current.next) {
                current = current.next;
            }
            current.next = node;
            node.prev = current;
        }
        ++this.length;
    }
    insert(position: number, element: any) {
        let current = this.list;
        let node = this.getNode(element);
        if (this.length > position && position >= 0) {
            if (position === 0) {
                node.next = current;
                this.list = node;
            } else {
                for (let i = 1; i < position; i++) {
                    current = current.next;
                }
                current.next.prev = node;
                node.next = current.next;
                current.next = node;
                node.prev = current;
            }
            ++this.length
        } else {
            this.append(element);
        }
    }
    removeAt(position: number) {
        if (this.length > position && position >= 0) {
            if (position === 0) {
                this.list = this.list.next;
            } else {
                let current = this.list;
                for (let i = 1; i < position; i++) {
                    current = current.next;
                }
                if(current.next && current.next.next){
                    current.next.next.prev = current;
                    current.next = current.next.next;
                }else if(current.next && !current.next.next){
                    current.next = null;
                }
            }
            --this.length
        }
    }
    remove(element: any) {
        this.removeAt(this.indexOf(element))
    }
    indexOf(element: any): number {
        let index = -1;
        let current = this.list;
        for (let i = 0; i < this.length; i++) {
            if (current.element === element) {
                return i
            }
            current = current.next;
        }
        return -1
    }
    isEmpty(): boolean {
        return this.length === 0;
    }
    size(): number {
        return this.length;
    }
    getHead() {
        return this.list;
    }
    toString(): string {
        var string: 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();

BOM

不同的 frame window 对象不同。

窗口位置

X 坐标:screenLeft 和 screenX 

Y 坐标:screenTop 和 screenY

moveTo(移动至某点) 和 moveBy(移动距离)

窗口大小

// 现代浏览器器
window.innerWidth 和 window.innerHeight

// IE 8 以前
document.documentElement.clientWidth
document.documentElement.clinetHeight

// IE 的混杂模式
document.body.clientWidth
document.body.clinetHeight

// 修改窗口大小
window.resizeTo()
window.resizeBy()

location

属性名 例子 属性说明
href 完整的 URL 链接
protocol https 协议
hostname www.baidu.com 不带端口的服务器名称
port 8080 返回端口号
host www.baidu.com:80 返回服务器名称和端口号
pathname /filename/xxx.html 返回目录名和文件名
search ?q=aaa 查询字符串,到 # 号为止
hash #page 到结束
// 返回上一页,go(-1): 返回上一页,原页面表单中的内容会丢失;back(-1): 返回上一页,原页表表单中的内容会保留,一般还是back(-1)
history.go(-1)
history.back()

// 下一页
history.go(1)
history.forward()

URLSearchParams

用户将 URL 参数的结构解析成对象获取。a=111&b=222&c=333这种结构,实例会有以下方法用户获取 params 信息。

hash

前端路由的实现一般有两种方式:

hash 的改变并不会触发页面的跳转,所以现在的 SPA 基本上都是基于 hash 实现的,URL 中锚点的取值是从 #到结束,而参数是取自 ?到# 之间。所以 hash 后面带参数都会被认为是 hash,所以才能在现在前端路由中页面跳转带参数,将 hash 取出来再按照一定的规则进行处理得到路由的配置,执行不同的实例。

hashchange

hash 改变路由需要有监听,主要的监听方式由 hashchange 实现,当路由发生改变时会触发。

window.addEventListener('hashchange', function(){}, false);

state change

这种的实现主要是为了短暂的记录当前页面的状态。可能是 ajax 获取到了页面的数据,渲染页面,当页面返回时能从页面的状态中获取数据直接用于渲染

popstate

历史发生改变时都会触发,需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用 JavaScript 调用 back、forward、go 方法时才会触发。

window.onpopstate = function (event) {
  console.log('location: ' + document.location);
  console.log('state: ' + JSON.stringify(event.state));
};

// 或者

window.addEventListener('popstate', function(event) {
  console.log('location: ' + document.location);
  console.log('state: ' + JSON.stringify(event.state));
});

history.pushState

history.pushState 会让 URL 立即发生改变,但是页面并不会发生任何改变,只是历史记录中多了条记录,如果设置的是锚点也不会触发 hashchange 事件。包含以下参数:

  • state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
  • title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
  • url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。url必须同域,不能跨域
history.pushState({page: 2}, 'title 2', '?page=2');

history.replaceState

replaceState 和 pushState 相同,replace 是替换,push 是新增。

history.replaceState({page: 3}, 'title 3', '?page=3');