JavaScript学习笔记内容较多较杂,适合稍有基础偏进阶

JavaScript学习笔记 内容较多较杂,适合稍有基础偏进阶


前言:

个人的JavaScript学习笔记,方便自己忘了东西回来复习

小知识

  1. DOM 属性不总是字符串类型的(大部分是字符串类型),input.checked是布尔型,style是对象。
  2. 特性(Attributes)可以转为属性(properties),属性不能转为特性。
  3. HTML特性总是不分大小写,并且他们大多是字符串类型。
  4. 用JavaScript渲染html的时候,当在后面想除去这个修改,比如说背景颜色呀,字体颜色呀这种,不要用delete,直接置空就好,例如:document.body.style.background=""就恢复原样相当于没修改了
  5. 关于对象,对象有属性、方法,有两种方式访问他们。一种是objectName.propertyName另一种是objectName["propertyName"],对象里可以有多个属性,但需要注意的是,对象语法里不能用“=”而要用“:”,例如:
var person={
            firstname:"John",
            lastname:"Doe",
            id:5566
        };

特性工具

  • elem.hasAttribute(name) — 检查特性是否存在。
  • elem.getAttribute(name) — 获取这个特性值。
  • elem.setAttribute(name, value) — 设置这个特性值。
  • elem.removeAttribute(name) — 移除这个特性。

浏览器事件简介

(应该放在DOM版块里,但主要应用于JavaScript,所以放在这里总结)

鼠标事件:

  1. click —— 当鼠标点击一个元素时(触摸屏设备会在点击时生成)。
  2. contextmenu —— 当鼠标右键点击一个元素时。
  3. mouseover / mouseout —— 当鼠标指针移入/离开一个元素时。
  4. mousedown / mouseup —— 当在元素上按下/释放鼠标按钮时。
  5. mousemove —— 当鼠标移动时。

键盘事件:

  1. keydown 和 keyup —— 当按下和松开一个按键时。

表单(form)元素事件:

  1. submit —— 当访问者提交了一个 <form> 时。
  2. focus —— 当访问者聚焦于一个元素时,例如聚焦于一个 <input>

Document 事件:

  1. DOMContentLoaded —— 当 HTML 的加载和处理均完成,DOM 被完全构建完成时。

CSS 事件:

  1. transitionend —— 当一个 CSS 动画完成时。

一些DOM牛逼函数

  1. prompt
    用法:prompt() 函数显示一条消息,并等待输入。第二个参数是默认的输入值,如果用户没有输入值,就会返回这个值。该函数返回用户输入的值或默认值。
    prompt(text,defaultinput)
    (单独用可能只是给变量提供一个字符串,但如果结合特性,就能起到不错的渲染效果)例如:
document.body.style.backgroundColor = prompt('background color?', 'green');

点确定,网页的body部分变为绿色,点否,无事发生。

  1. location(不能算是函数,其实是对象,这里介绍它是结合window.location)
    用法:Location 对象包含有关当前 URL 的信息。
    Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问。

如果只是location.href,那就是当前页面位置信息,但如果使用window.location.href=“一个链接” 就实现了类似于HTML里的<a></a>
既然可以用a标签,为什么使用window.location呢?因为放进函数里,可以实现先执行命令再跳转,例如:

function fun()
    {
        document.body.style.background="red";
        setTimeout(()=>document.body.style.background="",3000)
        window.location.href="https://www.php.cn/";
    }

代码比较简单,这里就不多解释了

  1. confirm
    用法:confirm函数用于提供确认功能,它首先显示给定的message参数所包含的信息,并提供两个可选择的回答“ok”和“cancel”,然后等待用户选择其中的一个。

我用的比较多的就是配合if使用,点击确定->返回ok->执行if语句
例如:

if(confirm("go to baidu?")){
            location.href="https://baidu.com";
        }

JavaScript讲究的就是个“动”,尤其是DOM,注重与用户的交互(个人拙见,后期学习发现有问题还会调整)

  1. getComputedStyle
    用法:读取css样式,style只对style有用,无法读取他们
    语法:getComputedStyle(element, [pseudo])
    element
    需要被读取样式值的元素。
    pseudo
    伪元素(如果需要),例如 ::before。空字符串或无参数则意味着元素本身。
    结果是一个具有样式属性的对象,像 elem.style,但现在对于所有的 CSS 类来说都是如此。

例如:

<head>
  <style> body { color: red; margin: 5px } </style>
</head>
<body>

  <script>
    let computedStyle = getComputedStyle(document.body);

    // 现在我们可以读取它的 margin 和 color 了

    alert( computedStyle.marginTop ); // 5px
    alert( computedStyle.color ); // rgb(255, 0, 0)
  </script>

</body>

一、创建新变量

1.var
2.let
3.const

前两者其实差不多,var的作用域被规定为一个函数作用域,而let则被规定为块作用域.因此let的作用范围会比var稍小一点,不过平时体现不明显,只有循环的时候会有体现。var定义的变量在整个函数都有被定义(也就是循环外也有),而let只在循环内有。还有就是被let声明的变量不会作为全局对象window的属性,而被var声明的变量可以。

那么什么时候用let什么时候用var呢?其实都可以…只是let对全局的污染会小一点,目前我还没发现有什么差别

var允许在同一作用域中声明同名的变量,而let不可以。
const又和let差不多,const和let都是在声明的块作用域中有效,不过需要注意的是let的申明是可以被改变的,而const不行,它必须立刻被初始化

const PI=3.141592653589;
PI=3.14;

像这样就会出错,只能保留第一行。

二、创建新元素/属性节点

1.appendChild(a)
2.insertBefore(a,b)
3.setAttributeNode(a)
前两个创建新元素节点,第三个创建新属性节点,用法一样,就不重复说明了
第一个就是添加元素(a)到尾部,第二个就是添加元素(a)到后一个参数(b)的前面。放一段代码便于理解。
对了,两个都需要在用之前告诉他们在哪个区域进行增加,比如下面代码的这一行,就是告诉他们要在”div1“里增加,还是比较好懂的。
下面代码里的“creat什么什么”的用法,我在下面讲

element.appendChild(para);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="div1">
        <p id="p1">这是一个段落</p>
        <p id="p2">这是另外一个段落</p>
    </div>
    <script>
        var para=document.createElement("p");
        var node=document.createTextNode("这是一个新的段落");
        para.appendChild(node);
        var element=document.getElementById("div1");
        element.appendChild(para);
        //添加新元素到尾部
    </script>
</body>
</html>

这段代码的效果是这样的:

这是一个段落

这是另外一个段落

这是一个新的段落
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="div1">
        <p id="p1">这是一个段落。</p>
        <p id="p2">这是另外一个段落。</p>
    </div>
    <script>
        var para=document.createElement("p");
        var node=document.createTextNode("这是一个新的段落");
        para.appendChild(node);
        var element=document.getElementById("div1");
        var child=document.getElementById("p1");
        element.insertBefore(para,child);
        //添加元素到头部
    </script>
</body>
</html>

这段代码的效果是这样的:

这是一个新的段落

这是一个段落。

这是另外一个段落。

三、creat三兄弟

1.createElement(”元素“)
这个用法比较简单也比较好理解,就是在引号里面放元素就好,比如:p、button…
2.creatTextNode(”文本“)
这个就是创建一个文本节点,一般是和1一起使用,下面是例子:

        var para=document.createElement("p");//A
        var node=document.createTextNode("这是一个新的段落");//B
        para.appendChild(node);//C

A:申明一个变量para,它的属性是p(现在没有任何内容)
B:申明一个变量node,它的文本节点是双引号里的内容
C:结合“二、创建新元素节点”所讲内容,“para”:告诉appendChild要在“para”这个区域加东西。括号里的“node”,则是把node加在para上,简单来说就是把文本节点放在这个元素里
3.creatAttribute(“属性”)
这个就是给原本的内容加属性,换颜色什么的,这个函数我不知道常用不,但挺难理解的比起前两个。所以这个我先放代码再结合代码讲

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <style>
        .democlass{
            color:red;
        }
        </style>
        </head>
        <body>
        
        <h1>Hello World</h1>
        <p id="demo">单击按钮来创建一个“类”属性值“democlass”插入到上面的H1元素。</p>
        <button onclick="myFunction()">点我</button>
        <script>
        function myFunction(){
            var h1=document.getElementsByTagName("H1")[0];
            var att=document.createAttribute("class");
            att.value="democlass";
            h1.setAttributeNode(att);
        }
        </script>
        
        </body>
</body>
</html>

中间的getElementsByTagName就和getElementsById差不多,这个我们后面再说。
先看最上面css那里,我们是用的.democlass,也就是说这个选择器是class选择器(关于css选择器可以在我的另一个文章里看,很短),也就是class属性,因此createAttribute后加的是(“class”)。后面几行其实和上面差不多,只不过因为我们加的不是元素而是属性,所以不能用appen或者insert,而是setAttributeNode

如果我们修改一下代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style type="text/css">
#democlass{
	color:red;
}
</style>
</head>
<body>

<h1>Hello World</h1>
<p id="demo">单击按钮来创建一个“类”属性值“democlass”插入到上面的H1元素。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
	var h1=document.getElementsByTagName("H1")[0];
	var att=document.createAttribute("id");
	att.value="democlass";
	h1.setAttributeNode(att);
}
</script>

</body>
</html>

把css里的“.”换成“#”,下面的createAttribute就要跟(“id”)

att.value="democlass";
h1.setAttributeNode(att);

这句话很好理解,就是让att得到名为democlass的属性,再把它插入给h1

四、搜索

这是很重要的部分,因为容易搞混或者搞忘,重点重点!!

1.getElement*
它最多最常用的就是getElementBy*,比如:getElementById、getElementByTagName、getElementsByClassName、getElementsByName

  • getElementById
  • getElementByTagName
  • getElementByName
  • getElementByClassName

通过它的名字也可以看出它的用法,分别是通过id找、通过元素类型找、通过class属性找、直接通过name找(很少用)
因为ById的用法比较常见,我这里就不多说了,说一下ByTagName和ByClassName
首先说ByClassName:

<form name="my-form">
  <div class="article">Article</div>
  <div class="long article">Long article</div>
</form>

<script>
  // 按 name 特性查找
  let form = document.getElementsByName('my-form')[0];

  // 在 form 中按 class 查找
  let articles = form.getElementsByClassName('article');
  alert(articles.length); // 2, 找到两个属性名里有“artical”
</script>

得到的结果是2,因为有两个clss里都找到了“artical”。
那么为什么

let form = document.getElementsByName('my-form')[0];

这里要用[0]呢,因为getElementsBy* 都是返回的集合,而不是元素也不是数组,但是可以使用调用数组的方法,[0]就是第一个,依次类推。

getElementsByTagName其实也是同理,同样是返回集合,所以在上一节同样是getElementsByTagName(“h1”)[0],意思是找到第一个h1属性。

2.querySelector*
这个比上面的少,就两个

  • querySelector(css)
  • querySelectorAll(css)
    第一个是返回找到的第一个,第二个是返回找的到所有的一个集合
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<h2 class="example">class="example" 的标题</h2>
<p class="example"> class="example" 的段落。</p> 
<p>点击按钮为第一个 class="example" 的元素添加背景颜色。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction() {
    document.querySelector(".example").style.backgroundColor = "red";
}
</script>

</body>
</html>

我们有三个example,但是querySelector(".example")只返回第一个。
这里注意一下,因为是querySelector(css),所以括号里基本上是“.”或者“#”这两种,当然我指的是用“class和id”取了名字的,如果用的是元素类型,比如p、h1这种就不需要
querySelectorAll差不多,只是是个集合而已,就不多说了。

两个方式最大的不同
getElementsBy*是返回一个实时的集合,而querySelectorAll是返回一个静态的集合,放两段代码

<div>First div</div>

<script>
  let divs = document.getElementsByTagName('div');
  alert(divs.length); // 1
</script>

<div>Second div</div>

<script>
  alert(divs.length); // 2
</script>

可以看到,第一个script里长度只有1,但是在两个script中间加一个div,它的长度还是会被计算进去

<div>First div</div>

<script>
  let divs = document.querySelectorAll('div');
  alert(divs.length); // 1
</script>

<div>Second div</div>

<script>
  alert(divs.length); // 1
</script>

而这里当我调用document.querySelectorAll(‘div’)后,它只会执行到我调用这里,当执行后我的集合就被定死了,不会改变了,所以就算我再加div,我的长度也还是1。

五、插入

  1. 元素或文本插入方法:
  • node.append(…nodes or strings) —— 在 node 末尾 插入节点或字符串
  • node.prepend(…nodes or strings) —— 在 node 开头 插入节点或字符串,
  • node.before(…nodes or strings) —— 在 node 前面 插入节点或字符串,
  • node.after(…nodes or strings) —— 在 node 后面 插入节点或字符串,
  • node.replaceWith(…nodes or strings) —— 将 node 替换为给定的节点或字符串。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ol id="ol">
        <li>0</li>
        <li>1</li>
        <li>2</li>
    </ol>
    <script>
        ol.before('brfore');
        ol.after('after');
        let liFirst=document.createElement('li');
        liFirst.innerHTML='prepend';
        ol.prepend(liFirst);
        let liLast=document.createElement('li');
        liLast.innerHTML='append';
        ol.append(liLast);
        
    </script>
</body>
</html>

完成插入后,相当于:

before
<ol>
  <li>prepend<li>
  <li>append<li>
  <li>0<li>
  <li>1<li>
  <li>2<li>
<ol>
after
  1. 插入HTML
  • insertAdjacentHTML/Text/Element

使用格式:elem.insertAdjacentHTML(where, html)。

该方法的第一个参数是代码字(code word),指定相对于 elem 的插入位置。必须为以下之一:

  1. “beforebegin” — 将 html 插入到 elem 前插入,
  2. “afterbegin” — 将 html 插入到 elem 开头,
  3. “beforeend” — 将 html 插入到 elem 末尾,
  4. “afterend” — 将 html 插入到 elem 后。

例如:

<div id="div"></div>
<script>
  div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
  div.insertAdjacentHTML('afterend', '<p>Bye</p>');
</script>

产生的效果是:

<p>Hello</p>
<div id="div"></div>
<p>Bye</p>
  1. 节点移除
    node.remove()
    挺简单的,就不多论述了
  2. 克隆节点
    elem.cloneNode(true):
    克隆 — 具有所有特性(attribute)和子元素。如果我们调用
    elem.cloneNode(false):
    克隆不具有子元素
<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<div class="alert" id="div">
  <strong>Hi there!</strong> You've read an important message.
</div>

<script>
  let div2 = div.cloneNode(true); // 克隆消息
  div2.querySelector('strong').innerHTML = 'Bye there!'; // 修改克隆

  div.after(div2); // 在已有的 div 后显示克隆
</script>

六、数组操作方法

添加:
unshift() 在第一位新增一或多个数据,返回长度

 var a=['a','b','c'];
 var len=a.unshift('o');
 console.log(len);//4
 console.log(a);//o,a,b,c

push() 在最后一位新增一或多个数据,返回长度

 var a=['a','b','c'];
 var len=a.push('o');
 console.log(len);//4
 console.log(a);//a,b,c,o

删除:
pop() 删除最后一位,并返回删除的数据

 var a=['a','b','c'];
 var b=a.pop();
 console.log(b);//c
 console.log(a);//a,b

shift() 删除第一位,并返回删除的数据

  
     var a=['a','b','c'];
     var b=a.shift();
     console.log(b);//a
     console.log(a);//b,c

合并:
concat() 合并数组,并返回合并之后的数据

var a=['a','b','c'];
var b=['d','e'];
var c=a.concat(b);
console.log(c);//a,b,c,d,e;

转换:
join() 根据指定分隔符将数组中的所有元素放入一个字符串,并返回这个字符串。

     var a=['a','b','c'];
     console.log(a.join());//a,b,c;
     console.log(a.join("-"))//a-b-c;
     console.log(a);//[a,b,c]原数组不会改变

倒置:
reverse() 颠倒数组中元素的顺序。

var a=['a','b','c'];
console.log(a.reverse());//c,b,a
console.log(a);//c,b,a 原数组也会被改变

截取:
slice() 可从已有的数组中返回选定的元素。该方法接收两个参数slice(start,end),strat为必选,表示从第几位开始;end为可选,表示到第几位结束(不包含end位),省略表示到最后一位;start和end都可以为负数,负数时表示从最后一位开始算起,如-1表示最后一位。

var a=['a','b','c','d'];
console.log(a.slice(1,3));//b,c
console.log(a.slice(1));//b,c,d
console.log(a.slice(-4,-2));//a,b
console.log(a.slice(-3));//b,c,d
console.log(a);//a,b,c,d  原数组不改变
 排序:

sort() 对数组中的元素进行排序,默认是升序。

    var a=[5,8,1,3,2,9,4,6,6];
     console.log(a.sort());//1,2,3,4,5,6,6,8,9
     console.log(a);//1,2,3,4,5,6,6,8,9  原数组改变
 但是在排序前,会先调用数组的toString方法,将每个元素都转成字符之后,再进行排序,此时会按照字符串的排序,逐位比较,进行排序。
     var a=[7,1000,338,28456];
     console.log(a.sort());//1000, 28456, 338, 7

如果需要按照数值排序,需要传参。
sort(callback) callback为回调函数该函数应该具有两个参数,比较这两个参数,然后返回一个用于说明这两个值的相对顺序的数字(a-b)。其返回值如下:
若 a 小于 b,返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。

  var a=[7,1000,338,28456];
     console.log(a.sort(fn));//7,338,1000,28456
     function fn(a,b){
         return a-b;
     }

添加,删除,替换
splice() 向数组中添加,或从数组删除,或替换数组中的元素,然后返回被删除/替换的元素
1. 不传参:无操作


     var a=['a','b','c','d','e'];
     console.log(a.splice());//[]
     console.log(a);//['a','b','c','d','e']
  1. 只传入start:表示从索引为start的数据开始删除,直到数组结束
 ```js
 var a=['a','b','c','d','e'];
 console.log(a.splice(2));//['c','d','e']
 console.log(a);//['a','b'] 原数组改变
 ```
  1. 传入start和num:表示从索引为start的数据开始删除,删除num个
 ```js
 var a=['a','b','c','d','e'];
 console.log(a.splice(2,2));//['c','d']
 console.log(a);//['a','b','e'] 原数组改变
 ```
  1. 传入更多:表示从索引为start的数据开始删除,删除num个,并将第三个参数及后面所有参数,插入到start的位置
 ```js
 var a=['a','b','c','d','e'];
 console.log(a.splice(2,2,'g','f'));//['c','d']
 console.log(a);//['a','b','g','f','e'] 原数组改变
 ```
  1. 传入更多:表示从索引为start的数据开始删除,删除num个,并将第三个参数及后面所有参数,插入到start的位置

    var a=['a','b','c','d','e'];
    console.log(a.splice(2,0,'g','f'));//[]
    console.log(a);//['a','b','g','f','c','d','e'] 原数组改变
    

    转换:
    toString() 转换成字符串,类似于没有参数的join()。该方法会在数据发生隐式类型转换时被自动调用,如果手动调用,就是直接转为字符串。

    var a=['a','b','c','d','e'];
    console.log(a.toString());//a,b,c,d,e
    console.log(a);//['a','b','c','d','e'] 原数组不改变
    

    查询:
    indexOf() 根据指定的数据,从左向右,查询在数组中出现的位置,如果不存在指定的数据,返回-1。该方法是查询方法,不会对数组产生改变.
    参数: indexOf(value, start);value为要查询的数据;start为可选,表示开始查询的位置,当start为负数时,从数组的尾部向前数;如果查询不到value的存在,则方法返回-1

    var a=['h','e','l','l','o'];
    console.log(a.indexOf('l'));//2
    console.log(a.indexOf('l',2));//3
    console.log(a.indexOf('k'))//-1
    console.log(a.indexOf("l",-3));//2
    

    lastIndexOf() 根据指定的数据,从右向左,查询在数组中出现的位置,如果不存在指定的数据,返回-1。该方法是查询方法,不会对数组产生改变。
    参数: lastIndexOf(value, start);value为要查询的数据;start为可选,表示开始查询的位置,当start为负数时,从数组的尾部向前数;如果查询不到value的存在,则方法返回-1

    var arr = ["h","e","l","l","o"];
    console.log(a.lastIndexOf("l"));//3
    console.log(a.lastIndexOf("l",3));//3
    console.log(a.lastIndexOf("l",1));//-1
    console.log(a.lastIndexOf("l",-3));//2
    console.log(a.lastIndexOf("l",-4));//-1
    

    遍历:
    forEach() 用来遍历数组,该方法没有返回值。

    var a=['a','b','c'];
    var b=[];
    a.forEach(function(item){
        b.push(item);
    })
    
    console.log(b);//a,b,c;
    
    

    map() 1.同forEach功能;2.map的回调函数会将执行结果返回,最后map将所有回调函数的返回值组成新数组返回。

    var a = [2,3,4,5];
    var b = a.map(function(x) {
         return x - 1;
    });
    console.log(a);//2,3,4,5
    console.log(b);//1,2,3,4
    

    some() 判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。与every相反,只要有一个回调函数的返回值都为true,some的返回值为true,所有回调函数的返回值为false,some的返回值才为false

    function fn(data){
        return data>10;
    }
    var a=[2,4,5,8,10,12];
    var b=[1,2,3,4,5];
    console.log(a.some(fn));//true
    console.log(b.some(fn));//false
    

    every() 判断数组中每一项是否都满足条件,只有所有项都满足条件,才会返回true。当回调函数的返回值为true时,类似于forEach的功能,遍历所有;如果为false,那么停止执行,后面的数据不再遍历,停在第一个返回false的位置。当每个回调函数的返回值都为true时,every的返回值为true,只要有一个回调函数的返回值为false,every的返回值都为false

    function fn(data){
        return data>10;
    }
    var a=[2,4,5,8,10,12];
    var b=[1,2,3,4,5];
    var c=[11,12,13,14];
    console.log(a.every(fn));//false
    console.log(b.every(fn));//false
    console.log(c.every(fn));//true
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值