分类: 笔记

  • 常用事件

    焦点事件

    事件名称何时触发
    focus元素获得焦点(不会冒泡)。
    blur元素失去焦点(不会冒泡)。

    表单事件

    事件名称何时触发
    reset点击重置按钮时
    submit点击提交按钮

    视图事件

    事件名称何时触发
    resize文档视图大小被改变
    scroll文档视图或元素已经滚动

    剪贴板事件

    事件名称何时触发
    cut已经剪贴选中的文本内容并且复制到了剪贴板。
    copy已经把选中的文本内容复制到了剪贴板。
    paste从剪贴板复制的文本内容被粘贴。

    键盘事件

    事件名称何时触发
    keydown按下任意按键。
    keypress除 Shift、Fn、CapsLock 外的任意键被按住。(连续触发。)
    keyup释放任意按键。

    鼠标事件

    事件名称何时触发
    click在元素上按下并释放任意鼠标按键。
    contextmenu右键点击(在右键菜单显示前触发)。
    dblclick在元素上双击鼠标按钮。
    mousedown在元素上按下任意鼠标按钮。
    mouseenter指针移到有事件监听的元素内。
    mouseleave指针移出元素范围外(不冒泡)。
    mousemove指针在元素内移动时持续触发。
    mouseover指针移到有事件监听的元素或者它的子元素内。
    mouseout指针移出元素,或者移到它的子元素上。
    mouseup在元素上释放任意鼠标按键。
    pointerlockchange鼠标被锁定或者解除锁定发生时。
    pointerlockerror可能因为一些技术的原因鼠标锁定被禁止时。
    select有文本被选中。
    wheel滚轮向任意方向滚动。

    值变化事件

    input

    input – Web API 接口参考 | MDN

    存储事件

    change

    change – Web API 接口参考 | MDN


    事件参考 | MDN

  • CSS 属性选择器

    CSS 属性选择器通过已经存在的属性名或属性值匹配元素。

    语法

    [attr]

    表示带有以 attr 命名的属性的元素。

    [attr=value]

    表示带有以 attr 命名的属性,且属性值为 value 的元素。

    [attr~=value]

    表示带有以 attr 命名的属性的元素,并且该属性是一个以空格作为分隔的值列表,其中至少有一个值为 value。

    [attr|=value]

    表示带有以 attr 命名的属性的元素,属性值为“value”或是以“value-”为前缀(”-“为连字符,Unicode 编码为 U+002D)开头。典型的应用场景是用来匹配语言简写代码(如 zh-CN,zh-TW 可以用 zh 作为 value)。

    [attr^=value]

    表示带有以 attr 命名的属性,且属性值是以 value 开头的元素。

    [attr$=value]

    表示带有以 attr 命名的属性,且属性值是以 value 结尾的元素。

    [attr*=value]

    表示带有以 attr 命名的属性,且属性值至少包含一个 value 值的元素。

    [*attr* *operator* *value* i]

    在属性选择器的右方括号前添加一个用空格隔开的字母 i(或 I),可以在匹配属性值时忽略大小写(支持 ASCII 字符范围之内的字母)。

    [*attr* *operator* *value* s]

    在属性选择器的右方括号前添加一个用空格隔开的字母 s(或 S),可以在匹配属性值时区分大小写(支持 ASCII 字符范围之内的字母)。

    示例

    CSS

    a {
      color: blue;
    }
    
    /* 以 "#" 开头的页面本地链接 */
    a[href^="#"] {
      background-color: gold;
    }
    
    /* 包含 "example" 的链接 */
    a[href*="example"] {
      background-color: silver;
    }
    
    /* 包含 "insensitive" 的链接,不区分大小写 */
    a[href*="insensitive" i] {
      color: cyan;
    }
    
    /* 包含 "cAsE" 的链接,区分大小写 */
    a[href*="cAsE" s] {
      color: pink;
    }
    
    /* 以 ".org" 结尾的链接 */
    a[href$=".org"] {
      color: red;
    }
    

    HTML

    <ul>
      <li><a href="#internal">Internal link</a></li>
      <li><a href="http://example.com">Example link</a></li>
      <li><a href="#InSensitive">Insensitive internal link</a></li>
      <li><a href="http://example.org">Example org link</a></li>
    </ul>
    

    结果

    另外

    由于 type 属性主要用于 <input> 元素,因此 HTML 规范要求 type 属性的匹配不区分大小写,如果使用属性选择器且添加了 大小写敏感 的修饰符,那么将无法与type属性进行匹配。

    属性选择器 – CSS(层叠样式表) | MDN

  • 立即执行函数

    作用

    创造一个作用域空间,防止变量冲突或覆盖.

    • 立即执行
    • 只执行一次
    • 执行完毕,立即销毁

    两种写法

    (function (){}()) //W3C推荐写法
    
    (function (){})()
    

    为什么立即执行函数外面要加(),不加可不可以呢,我们来试一下

    function(){ 
       console.log('this is a function')
    }()
    //Uncaught SyntaxError: Function statements require a function name
    //报错,意思是函数声明需要一个函数名
    

    虽然匿名函数属于函数表达式,但未进行赋值,所以javascript解析时将开头的function当做函数声明,故报错提示需要函数名;

    立即执行函数里面的函数必须是函数表达式

    函数声明和函数表达式区别
    let func = function() {
        return 1;
    }();
    console.log(func) //1 
    

    为什么给一个匿名函数赋值就可以正常了呢?

    匿名函数前加了 “=” 有了运算符后,将函数声明转化为函数表达式。

    我们可以理解为在匿名函数前加了 “=” 有了运算符后,将函数声明转化为函数表达式。

    我们拿!,+,-,()…等运算符来进行测试:
    !function(){
        console.log('this is a function1')
    }()
    // this is a function1
        
    +function(){
        console.log('this is a function2')
    }()
    // this is a function2
        
    -function(){
        console.log('this is a function3')
    }()
    // this is a function3
        
    ;(function(){
        console.log('this is a function4')
    })()
    // this is a function4
    

    由此可见,加运算符确实可将函数声明转化为函数表达式

    需要注意的地方

    注意在代码console.log(‘this is a function4’)这个函数我在最前面加上了一个“;”(分号) 为什么要加这分号,不加行不行呢,大家可以验证一下。 不加会报错(Uncaught TypeError: (intermediate value)(…) is not a function)

    上面的代码有一些多,我们截取一部分来讲
    -function(){
        console.log('this is a function3')
    }()
    
    (function(){
        console.log('this is a function4')
    })()
    

    这段代码一样会报错,因为ECMAScript规范具有分号自动插入规则,但是在上面代码中,在第一个立即执行函数末尾却不会插入,因为第二个立即执行函数,会被解释为如下形式:

    -function(){
        console.log('this is a function3')
    }()(function(){console.log('this is a function4')})()
    

    因此我们在最后一个立即执行函数前面加一个分号;(是为了防止前一个立即函数尾部没有的分号;) 其实还有其它的方式也可以实现,使用void 运算符,个人感觉这种方式更优雅

    -function(){
        console.log('this is a function3')
    }()
    
    void (function(){
        console.log('this is a function4')
    })()
    

    立即执行函数的应用场景

    1、代码在页面加载完成之后,不得不执行一些设置工作,比如时间处理器,创建对象等等.

    2、所有的这些动作只需要执行一次,比如只需要显示一个事件.

    3、将代码包裹在它的局部作用域中,不会让任何变量泄漏成全局变量.

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/xu_song/article/details/107077675

  • 函数声明、函数表达式、匿名函数

    函数声明

    function func() { console.log('this is a function') };
    

    首先使用 function 关键字声明一个函数,再执行一个函数名,叫函数声明。

    函数表达式

    let func = function() { console.log('this is a function') };
    

    使用 function 关键字声明一个函数,但未给函数命名,将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。

    匿名函数

    function() { console.log('this is a function') };
    

    使用 function 关键字声明一个函数,但未给函数命名,所以叫匿名函数,匿名函数属于函数表达式,匿名函数有很多作用,赋予一个变量则创建函数,赋予一个事件则成为事件处理程序或创建闭包等等。

    函数声明和函数表达式区别

    1、JavaScript 引擎在解析 JavaScript 代码时会“函数声明提升”当前执行环境(作用域)上的函数声明,而函数表达式必须等到 JavaScript 引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。

    2、函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以 func() 形式调用。

    我们看一下下面的例子就会明白

    函数声明

    func(); //正常输出this is a function
    function func() {
        console.log('this is a function') 
    }; 
    

    函数表达式

    func();// Uncaught SyntaxError: Invalid or unexpected token
    //函数表达式报错,func未保存对函数的引用,函数调用需放在函数表达式后面
    var func = function() { 
        console.log('this is a function') 
    };
    

    版权声明:本文为CSDN博主「xu_song」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/xu_song/article/details/107077675

  • vw与vh

    vw和vh单位是相对于视口的尺寸所计算的结果

    • vw(viewport width)
      • 1vw = 视口宽度的 1%
    • vh(viewport height)
      • 1vh = 视口高度的 1%

    vw单位的适配:

    • 确定设计稿的宽度(视口的宽度),得到 1vw = 视口宽度的1%
    • vw单位的尺寸 = px / 1vw = px / 视口的宽度的1%

    vh单位的适配:

    • 确定设计稿的高度(视口的高度),得到 1vh = 视口高度的1%
    • vh单位的尺寸 = px / 1vh = px / 视口高度的1%
    例如:

    此时视口宽度1920px 高度1080px

    1vw = 1920px / 100 = 19.2 px

    1vh = 1080px / 100 = 10.8px

  • rem布局

    rem布局进行的是元素等比例缩放

    em:相对于当前元素的字体大小 → 1em = 当前标签的font-size

    rem:相对于根元素(html)的字体大小 → 1rem = html标签的font-size

    浏览器默认的font-size的大小为16px

    rem布局原理

    屏幕尺寸改变时,通过改变html标签的font-size使元素自适应

    怎么使用rem布局

    媒体查询

    1.根据设计图尺寸,把px单位转换成rem单位

    px值 = rem单位 * html标签的font-size

    • rem = px / html标签的font-size
    • 为了计算方便,一般我们会针对于设计图的大小自定义一个html标签的font-size的大小
    确定比例

    比如设计图宽度为375px,确定比例为1:10,则html的font-size设置为37.5px

    2.利用媒体查询,当屏幕尺寸变化时,更改html标签的font-size

    @media screen and (min-width:375px) {
        html {
            font-size: 37.5px;
        }
    }
    @media screen and (min-width:750px) {
        html {
            font-size: 75px;
        }
    }
    
    /* ...... */ 
    

    注意点:为了保证大屏的媒体查询不被覆盖,媒体查询一般从小屏往大了写。

    flexible.js

    直接引入flexible.js文件即可

    比例:屏幕宽度 / html的font-size = 10

    rem = px / html的font-size

  • 媒体查询

    根据不同屏幕的宽度改变样式.

    语法

    @media screen and (条件) { } /* 满足条件则生效 */
    

    条件

    条件含义解释
    min-width样式生效的最小宽当屏幕宽度大于>=该宽度时,选择器样式才生效
    max-width样式生效的最大宽当屏幕宽度<=该宽度时,选择器样式才生效
    width样式生效的宽度当屏幕宽度正好=该宽度时,选择器样式才生效

    注意点:

    • 媒体查询只能控制选择器是否生效,不能提升选择器优先级!
    • 媒体查询中可以同时设置多个条件,条件之间以and连接
    • 媒体查询语法格式中空格不要省略

    为了保证大屏的媒体查询不被覆盖,媒体查询一般从小屏往大了写。

  • 自定义属性

    固有属性

    标签天生自带的属性 比如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