作者: liao

  • 自定义属性

    固有属性

    标签天生自带的属性 比如class id title等, 可以直接使用点语法操作

    自定义属性

    自己添加的属性,在DOM对象中找不到,无法使用点语法操作,必须使用专门的API.

    getAttribute('属性名') // 获取自定义属性
    
    setAttribute('属性名', '属性值') // 设置自定义属性
    
    removeAttribute('属性名') // 删除自定义属性

    注意点:attribute方法可以操作标签的自定义属性和固有属性

    data-自定义属性

    传统的自定义属性没有专门的定义规则,开发者随意定值,不够规范,所以在html5中推出来了专门的data-自定义属性 在标签上一律以data-开头

    dataset属性存取data-*自定义属性的值

    这种方式通过访问一个元素的dataset属性来存取data-*自定义属性的值。这个dataset属性是HTML5 Javascript API的一部分,用来返回一个所有选择元素的data-*属性的DOMStringMap对象。

    使用这种方法时,不是使用完整的属性名,如data-id来存取数据,应该去掉data-前缀。

    还有一点特别注意的是:data-属性名如果包含了连字符,例如 data-id-and-class,连字符将被去掉,并转换为驼峰式的命名,前面的属性应该写成idAndClass。

    <div id="div1" class="div1" data-id = "myId" data-class = "myClass" data-id-and-class = "Hello"></div>
    <script>
        var div = document.getElementById("div1");
    
        var attr = div.attributes;
        console.log(attr);      //NamedNodeMap对象
        var data = div.dataset;
        console.log(data);      //DOMStringMap对象
    
        var id = div.id;
        console.log(id);        //div1
    
        var myId = div.dataset.id;
        console.log(myId);      //myId
        var iac = div.dataset.idAndClass;
        console.log(iac);       //Hello
    </script>

    如果你想删掉一个data-属性,可以这么做:

    delete div.dataset.id;

    HTML5中的data-*自定义属性 – 知乎

  • js本地存储

    localStorage

    • 生命周期永久生效,除非手动删除 否则关闭页面也会存在
    • 可以多窗口(页面)共享(同一浏览器可以共享)
    • 以键值对的形式存储使用

    localStorage 中的键值对总是以字符串的形式存储。 (需要注意, 和js对象相比, 键值对总是以字符串的形式存储意味着数值类型会自动转化为字符串类型).

    存储数据

    localStorage.setItem(key,value)

    获取数据

    localStorage.getItem(key)

    删除数据

    localStorage.removeItem(key)

    删除所有数据

    localStorage.clear()

    Window.localStorage – Web API 接口参考 | MDN

    存储复杂数据类型存储

    本地只能存储字符串,无法存储复杂数据类型.需要将复杂数据类型转换成JSON字符串,在存储到本地

    JSON.stringify(复杂数据类型)

    将复杂数据转换成JSON字符串

    存储的时候使用

    JSON.parse(JSON字符串)

    将JSON字符串转换成对象

    取出的时候使用

    sessionStorage

    • 生命周期为关闭浏览器标签页
    • 在同一个窗口(页面)下数据可以共享
    • 以键值对的形式存储使用
    • 用法跟localStorage基本相同
  • window对象

    location

    对象

    常用属性和方法:

    href属性获取完整的 URL 地址,对其赋值时用于地址的跳转

    //获取当前url地址
    console.log(location.href)
    //跳转到目标地址
    location.href = 'https://api.liaooo.cn'
    

    search属性获取地址中携带的参数,符号?后面部分

    //--- https://api.liaooo.cn/?s=123
    console.log(location.search)
    // ?s=123
    

    hash属性获取地址中的啥希值,符号#后面部分

    //--- https://api.liaooo.cn/#site-header
    console.log(location.hash)
    // '#site-header'
    

    reload方法用来刷新当前页面,传入参数true时表示强制刷新

    location.reload(true) //默认为false 强制刷新(重新从服务器获取资源)
    

    对象

    常用属性和方法:

    通过userAgent检测浏览器的版本及平台

    // 检测 userAgent(浏览器信息)
    !(function () {
    	const userAgent = navigator.userAgent
    	// 验证是否为Android或iPhone
    	const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
    	const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
    	// 如果是Android或iPhone,则跳转至移动站点
    	if (android || iphone) {
    		location.href = 'https://api.liaooo.cn'
    	}
    })()
    

    histroy

    对象

    向前和向后跳转

    //这和用户点击浏览器回退按钮的效果相同
    
    //回到上一个页面
    history.back()
    
    //去到下一个页面
    window.history.forward()
    

    跳转到 history 中指定的一个点

    //回到上一个页面 等同于调用 back()
    history.go(-1)
    
    //去到下一个页面 等同于调用了 forward()
    history.go(1)
    
    //类似地,你可以传递参数值2并向前移动2个页面,等等.
    

    可以通过查看长度属性的值来确定的历史堆栈中页面的数量:

    let numberOfEntries = history.length
    

    History API – Web API 接口参考 | MDN

  • js执行机制

    JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.

    单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务.

    这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉.

    同步和异步

    利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程.

    于是,JS 中出现了同步异步.

    同步

    前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。

    异步

    在做一件事的同时,还可以去处理其他事情.

    同步任务

    同步任务都在主线程上执行,形成一个执行栈

    异步任务

    JS 的异步是通过回调函数实现的


    一般而言,异步任务有以下三种类型:

    • 普通事件,如 click、resize 等
    • 资源加载,如 load、error 等
    • 定时器,包括 setInterval、setTimeout 等

    异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)

    异步JavaScript

    https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Asynchronous/Introducing

    通用异步编程概念

    https://developer.mozilla.org/zh-CN/docs/conflicting/Learn/JavaScript/Asynchronous/Introducing

    执行机制

    • 先执行执行栈中的同步任务
    • 异步任务放入任务队列中
    • 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

    主线程不断的重复获得任务、执行任务、再获取任务、再执行,这种机制被称为事件循环Event Loop

    并发模型与事件循环 – JavaScript | MDN

  • 定时器-延时函数

    setTimeout() / clearTimeout()

    语法:

    setTimeout(回调函数,延迟毫秒数)

    setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window

    清除延时函数

    let timer = setTimeout(回调函数,延迟毫秒数) //把定时器的ID给变量timer
    clearTimeout(timer) //通过ID清除定时器
    

    需要注意的是setTimeout()setInterval()共用一个编号池,技术上,clearTimeout()和 clearInterval()可以互换。但是,为了避免混淆,不要混用取消定时函数。

    同一个对象上(一个window或者worker),setTimeout()或者setInterval()在后续的调用不会重用同一个定时器编号。但是不同的对象使用独立的编号池。

    window.setTimeout – Web API 接口参考 | MDN

    结合递归函数让setTimeout()实现setInterval()的效果

    let i= 0
    function test(){
      i++
      setTimeout(test,1000)  //注意:setTimeout内的函数不需要写括号
      console.log(i);
    }
    test()
    

    两种定时器对比

    • setInterval() 的特征是重复执行,首次执行会延时
    • setTimeout() 的特征是延时执行,只执行 1 次
    • setTimeout() 结合递归函数,能模拟 setInterval() 重复执行
    • clearTimeout() 清除由 setTimeout() 创建的定时任务

    拓展

    console.log(111)
    
    setTimeout(function () {
      console.log(222)
    	}, 0)
    
    console.log(333)
    
    //结果 111 333 222
    

    详见js执行机制

  • BOM

    BOM ( Browser Object Model ) 是浏览器对象模型

    window 对象下包含了 navigatorlocationdocumenthistoryscreen 5个属性,即所谓的 BOM (浏览器对象模型)

    • 全局变量是 window 对象的属性
    • 全局函数是 window 对象的方法

    注:依附于 window 对象的所有属性和方法,使用时可以省略 window

    Window – Web API 接口参考 | MDN

  • resize事件

    文档视图调整大小时会触发 resize 事件.

    resize事件仅在window对象上触发.

    只有在window对象上注册的处理程序才会接收resize事件.

    window.addEventListener('resize',function(){})

    检测屏幕宽度

    window.addEventListener('resize',function(){
    	let w = document.documentElement.clientWidth
    	console.log(w)
    })

    Window: resize event – Web APIs | MDN

  • scroll/offset/client获取宽高、位置

    scroll

    获取宽高

    scrollWidth

    只读

    Element.scrollWidth 这个只读属性是元素内容宽度的一种度量,包括由于overflow溢出而在屏幕上不可见的内容。

    scrollWidth的值等于内容的width + padding(包含伪元素,不包含滚动条)

    注意是内容的宽度,包括溢出的内容,无论是否隐藏溢出的内容.(scrollHeight同理)

    Element.scrollWidth – Web API 接口参考 | MDN

    scrollHeight

    只读

    Element.scrollHeight 这个只读属性是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。

    scrollHeight的值等于内容的height + padding(不包含滚动条)

    Element.scrollHeight – Web API 接口参考 | MDN

    获取位置

    scrollTop

    读 / 写

    Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数.

    • 一个元素的 scrollTop 值是这个元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。
    • 当一个元素的内容没有产生垂直方向的滚动条,那么它的 scrollTop 值为0.

    简单理解:向下滚动多少

    例:

    //检测页面滚动的头部距离(被卷去的头部)
    document.documentElement.scrollTop
    

    Element.scrollTop – Web API 接口参考 | MDN

    scrollLeft

    读 / 写

    Element.scrollLeft 属性可以读取或设置元素滚动条到元素左边的距离。

    Element.scrollLeft – Web API 接口参考 | MDN

    offset

    获取宽高

    offsetWidth / offsetHeight

    只读

    offsetWidth是测量包含元素的边框(border)、内边距(padding)、滚动条(scrollbar)(如果存在的话)、以及CSS设置的宽度(width)的值,不包含伪元素.

    它等于元素实际展现的宽度 / 高度

    例:

    <!-- css -->		
    <style>
    .box {
    	width: 100px;
    	height: 100px;
    	padding: 10px;
    	border: 1px solid #333;
    }
    </style>
    
    <!-- html -->
    <div class="box"></div>
    
    <!-- js -->
    <script>
    	let box = document.querySelector('.box')
      console.log(box.offsetWidth)   // 122 = width + padding + border
    	console.log(box.offsetHeight) // 122 =  height + padding + border
    </script>
    

    HTMLElement.offsetWidth – Web API 接口参考 | MDN

    HTMLElement.offsetHeight – Web API 接口参考 | MDN

    获取位置

    offsetTop / offsetLeft

    只读

    获取元素距离自己定位父级元素的上 / 左距离

    如果都没有则以文档左上角为准

    拓展阅读:HTMLElement.offsetParent – Web API 接口参考 | MDN

    client

    获取宽高

    clientWidth / clientHeight

    只读

    获取元素的可见部分宽高(不包含边框,滚动条等)

    Element.clientWidth – Web API 接口参考 | MDN

    获取位置

    clientTop / clientLeft

    只读

    获取上边框border和左边框border宽度

  • 滚动事件与加载事件

    滚动事件

    事件名:scroll

    文档视图或者一个元素在滚动时,会触发元素的scroll事件。

    例:

    //监听整个页面滚动
    window.addEventListener('scroll',function(){})
    //给 window 或 document 添加 scroll 事件
    

    监听某个元素的内部滚动直接给某个元素加即可.

    加载事件

    加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件.

    事件名:load

    当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。

    它与DOMContentLoaded不同,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。

    例:

    //监听页面所有资源加载完毕
    window.addEventListener('load',function(){})
    

    注意:不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件

    load | MDN

    事件名:DOMContentLoaded

    document添加

    当纯HTML被完全加载以及解析时,DOMContentLoaded 事件会被触发,而不必等待样式表,图片或者子框架完成加载。

    //监听页面DOM加载完毕:
    //给 document 添加 DOMContentLoaded 事件
    document.addEventListener('DOMContentLoaded',function(){})

    Document: DOMContentLoaded 事件 | MDN

  • transform变换后仍占据原来空间

    HTML

    <div class="wrapper">
    	<div></div>
    </div>

    CSS

    .wrapper {
    	width: 500px;
    	height: 100px;
    	border: 1px solid #000;
    	margin: 20px auto 0;
    }
    .wrapper div {
    	width: 100px;
    	height: 100px;
    	transform: translateX(400px);
    	background: lightblue;
    	transition: all 0.5s;
    }
    .wrapper div:hover {
    	transform: translateX(0px);
    }
    

    如图,元素通过translate位移改变位置后,仍占据原空间,transform: translateX(0px)可以使其回到原位.