# ECMAScript

规定了JS的语法和基本对象

# 基本语法

  • JavaScript 区分大小写,函数 getElementById 与 getElementbyID 是不同的
  • NaN:not a number 不是数字的数字类型类型
  • null:对象为空的占位符
  • undefined:如果一个变量没有给初始值,则会默认赋值为undefined
  • document.write("abc") //页面输出abc

# typeof

typeof "Bill"                 // 返回 "string"
typeof 3.14                   // 返回 "number"
typeof NaN                    // 返回 "number"
typeof false                  // 返回 "boolean"
typeof [1,2,3,4]              // 返回 "object"
typeof {name:'Bill', age:19}  // 返回 "object"
typeof new Date()             // 返回 "object"
typeof function () {}         // 返回 "function"
typeof myCar                  // 返回 "undefined" *
typeof null                   // 返回 "object"

# Function

//定义方式
function fun1(a,b){ document.write(a+2) };
var fun2 = function(a,b){ document.write(a+2) };

//常用属性
fun1.length() //2 参数的个数

//参数传递,以下都可以调用fun1方法
fun1()
fun1(a)
fun1(a,b)

//再方法声明中有一个内置的对象(数组)arguments,封装所有的参数
function fun1(){
	for(var i = 0; i<arguments.length; i++){
		document.write(arguments[i]);
	}
}

# function构造函数

//无形参格式
function 对象名(){
 函数体
}
//示例
function Person() {
	alert("hello");
}
var p = new Person();

//带参数格式
function 对象名(参数列表){
 函数体
}
//示例
function Person(a, b) {
	alert(a + "-" + b);
}
var p = new Person(10, 20);

//有属性格式 this代表当前对象
function 对象名(){this.属性名1 = 属性值1;this.属性名2 = 属性值2;
}
//示例
function Person() {
	this.name = "小明";
	this.age = 13;
}
var p = new Person();
alert(p.name + "-" + p.age);

# Array

//定义方式
var arr1 = new Array(1,2,3);
var arr2 = new Array(5); //,,,,
var arr3 = [1,2,3,4];

//方法
concat() //连接两个或多个数组,并返回已连接数组的副本
join() //将数组中的元素按照指定的分隔符拼接为字符串
sort() //对数组的元素进行排序
reverse() //反转数组中元素的顺序
forEach() //循环数组
toString() //将数组转换为字符串,并返回结果
includes() //检查数组是否包含指定的元素
indexOf() //在数组中搜索元素并返回其位置
isArray() //检查对象是否为数组

filter() //创建数组,其中填充了所有通过的数组元素,不会改变原始数组
map() //为每个数组元素调用函数的结果创建新数组
find() //返回数组中第一个通过的元素的值
findIndex() //返回数组中通过的第一个元素的索引

slice() //选择数组的一部分,并返回新数组
splice() //从数组中添加/删除元素

push() //将新元素添加到数组的末尾,并返回新的长度
pop() //删除数组的最后一个元素,并返回该元素
unshift() //将新元素添加到数组的开头,并返回新的长度
shift() //删除数组的第一个元素,并返回该元素

every() //用于检测数组中所有元素是否都符合指定条件,若符合返回true,否则返回false;
some() //用于检测数组中的元素是否有满足指定条件的,若满足返回true,否则返回false;

# Math

Math.round() //四舍五入 
Math.random() //随机数 范围(0,1]
Math.ceil() //向上取整 
Math.floor() //向下取整 
Math.abs() //绝对值
Math.sqrt() //开方
Math.pow(底数,几次方) 

# RegExp

定义规则:

  • 单个字符 []
    • [a]:一个a
    • [ab]:a或b
    • [a-zA-Z0-9]:a到z或A到Z或0到9中的一个
    • [_]:下划线
    • 特殊含义的单个字符:
      • \d:单个数字字符[0-9]
      • \w:单个单词字符[a-zA-Z]
      • \s:空白字符
      • . :匹配所有字符(不包括换行)
  • 量词符号
    • 问号 ?:表示出现0次或1次
    • 星号 * :表示出现0次或多次
    • 加号 + :表示出现1次或多次
    • {m,n} :表示 m<= 数量 <=n
      • {,n}:最多n次
      • {m,}:最少m次
  • 开始结束符号,严格模式,只要有无法成立正则的字符存在,即为false
    • ^ :表示开始
    • $ :表示结束
//创建
var reg1 = new RegExp("^\\w{6,12}$"); //\w前面需要加转义的\
var reg2 = /^\w{6,12}$/;
//方法
reg1.test(参数) //验证指定的字符串
reg1.exec(str) //将返回一个数组,其中存放匹配的结果。如果为找到匹配结果,则返回 null

//匹配td标签内容
<TD align="middle" bgColor="#FFFFFF">5</TD>
<TD align="left" bgColor="#ffffff">饶丽丽</TD>
//正则
<td[^>]*?>(.*?)</td>\s*<td[^>]*?>(.*?)</td>
//"<td"到">"之间不可能出现>符号,因此使用[^>]*?匹配所有的字符;
//".*?匹配任意多个字符
//\s* 匹配多个td标签之间的空格

# Global

全局对象,Global中封装的方法不需要对象就可以直接调用

encodeURI() //URL编码,只编码汉字
decodeURL() //URL解码

encodeURIComponent() //URL编码,所有字符都编码
decodeURIComponent() //URL解码

eval() //将JavaScript字符串作为脚本代码来执行

URI和URL的区别

URI标识资源的详细名称,包含资源名
URL定位资源的网络位置,包含http://
例如:
http://www.baidu.com/ 是URL
/a.html 是URI
http://baidu.com/a.html 即是URL也是URI

# BOM对象

Browser Object Model 浏览器对象模型
一般情况下,window代表了BOM对象,window对象是JavaScript的内置对象,使用window对象调用方法时可以省略window不写

window.innerWidth //浏览器窗口的宽度
window.innerHeight //浏览器窗口的高度

screen.width //屏幕宽度
screen.height //屏幕高度
screen.availWidth //屏幕可用宽度,减去诸如侧边栏
screen.availHeight //屏幕可用高度,减去诸如任务栏

windows.scrollTo(0,0) //把内容滚动到指定的坐标
windows.scrollBy(0,-200) //按照指定的像素值来滚动内容 往上滚动了两百个像素

window.location.href //返回当前页面的URL
window.location.hostname //返回 web 主机的域名 www.w3school.com.cn
window.location.pathname //返回当前页面的路径或文件名  /js/js_window_location.asp
window.location.protocol //返回使用的 web 协议(http: 或 https:)

window.history.back() //后退
window.history.forward() //前进
window.history.go() //加载history中的某个具体页面

window.confirm("sometext") //确认框
window.prompt("sometext","defaultText") //提示框

# DOM对象

# Document Object Model 文档对象模型

DOM是将标记型文档中所有内容(标签、文本、属性)都封装成对象,通过操作对象的属性或者方法,来达到操作或者改变HTML展示效果的目的

//获取元素对象的几种方式
document.getElementById() //获取对应元素对象,如果找不到返回null
document.getElementsByClassName() //得到一个元素数组,如果找不到返回空数组0
document.getElementsByName() //得到一个元素数组,如果找不到返回空数组0
document.getElementsByTagName() //得到一个元素数组,如果找不到返回空数组0
 
document.querySelector() //接收一个CSS选择符,返回与该模式匹配的第一个元素
document.querySelectorAll() //用于选择匹配到的所有元素

// query选择符选出来的元素及元素数组是静态的,而getElement这种方法选出的元素是动态的
// 静态的?意思是指选出的所有元素的数组,不会随着文档操作而改变

//操作元素对象的value属性值
<input type="text" id="t1" value="你好" />
var t1 = document.getElementById("t1");
alert(t1.value); //把t1元素,value属性值拿出来
t1.value = "你好吗"; //修改value属性值,你好吗

//创建元素
var pp =document.createElement("p");
var del=document.createElement("input");

//添加元素
var div=document.getEletementById("result");
div.appendChild(pp);
div.insertBefore(pp,del);//在div元素下的pp之前添加标签

//删除元素
xxx.remove();.removeChild()

//操作元素对象的class属性值
<span id="s1" class="ys1">hello,word</span>
var s1 = document.getElementById("s1");
alert(s1.className); //获取
s1.className = "ys2"; //修改
s1.style.color = "red" //修改style

//绑定多个函数
<input type="text" value="111" onclick="run1(),run2(),run3()" />
//js事件需要添加on,jquery不用

# addEventListener()

addEventListener() 方法用于向指定元素添加监听事件。且同一元素目标可重复添加,不会覆盖之前相同事件,配合 removeEventListener() 方法来移除事件

//使用方法:
document.getElementById(元素id).addEventListener("click", function(event){
  console.log("目标元素被点击了");
},false);

有三个参数

  • 事件名称,字符串,必填
  • 执行函数,必填
  • 触发类型,布尔型,可空
    • true:事件在捕获阶段执行
    • false:事件在冒泡阶段执行,默认是false
//鼠标事件
click 当用户点击某个对象时调用的事件句柄。
contextmenu 在用户点击鼠标右键打开上下文菜单时触发
dblclick 当用户双击某个对象时调用的事件句柄。
mousedown 鼠标按钮被按下。
mouseenter 当鼠标指针移动到元素上时触发。
mouseleave 当鼠标指针移出元素时触发
mousemove 鼠标被移动。
mouseover 鼠标移到某元素之上。
mouseout 鼠标从某元素移开。
mouseup 鼠标按键被松开。

//键盘事件
属性 描述 DOM
keydown 某个键盘按键被按下。
keypress 某个键盘按键被按下并松开。
keyup 某个键盘按键被松开。

//框架/对象(Frame/Object)事件
abort 图像的加载被中断。 ( )
beforeunload 该事件在即将离开页面(刷新或关闭)时触发
error 在加载文档或图像时发生错误。 ( ,)
hashchange 该事件在当前 URL 的锚部分发生修改时触发。
load 一张页面或一幅图像完成加载。
pageshow 该事件在用户访问页面时触发
pagehide 该事件在用户离开当前网页跳转到另外一个页面时触发
resize 窗口或框架被重新调整大小。
scroll 当文档被滚动时发生的事件。
unload 用户退出页面。 ()

//表单事件
blur 元素失去焦点时触发
change 该事件在表单元素的内容改变时触发( , , ,)
focus 元素获取焦点时触发
focusin 元素即将获取焦点是触发
focusout 元素即将失去焦点是触发
input 元素获取用户输入是触发
reset 表单重置时触发
search 用户向搜索域输入文本时触发 (

//剪贴板事件
copy 该事件在用户拷贝元素内容时触发
cut 该事件在用户剪切元素内容时触发
paste 该事件在用户粘贴元素内容时触发

//打印事件
afterprint 该事件在页面已经开始打印,或者打印窗口已经关闭时触发
beforeprint 该事件在页面即将开始打印时触发

//拖动事件
drag 该事件在元素正在拖动时触发
dragend 该事件在用户完成元素的拖动时触发
dragenter 该事件在拖动的元素进入放置目标时触发
dragleave 该事件在拖动元素离开放置目标时触发
dragover 该事件在拖动元素在放置目标上时触发
dragstart 该事件在用户开始拖动元素时触发
drop 该事件在拖动元素放置在目标区域时触发

//多媒体(Media)事件
abort 事件在视频/音频(audio/video)终止加载时触发。
canplay 事件在用户可以开始播放视频/音频(audio/video)时触发。
canplaythrough 事件在视频/音频(audio/video)可以正常播放且无需停顿和缓冲时触发。
durationchange 事件在视频/音频(audio/video)的时长发生变化时触发。
emptied The event occurs when the current playlist is empty
ended 事件在视频/音频(audio/video)播放结束时触发。
error 事件在视频/音频(audio/video)数据加载期间发生错误时触发。
loadeddata 事件在浏览器加载视频/音频(audio/video)当前帧时触发触发。
loadedmetadata 事件在指定视频/音频(audio/video)的元数据加载后触发。
loadstart 事件在浏览器开始寻找指定视频/音频(audio/video)触发。
pause 事件在视频/音频(audio/video)暂停时触发。
play 事件在视频/音频(audio/video)开始播放时触发。
playing 事件在视频/音频(audio/video)暂停或者在缓冲后准备重新开始播放时触发。
progress 事件在浏览器下载指定的视频/音频(audio/video)时触发。
ratechange 事件在视频/音频(audio/video)的播放速度发送改变时触发。
seeked 事件在用户重新定位视频/音频(audio/video)的播放位置后触发。
seeking 事件在用户开始重新定位视频/音频(audio/video)时触发。
stalled 事件在浏览器获取媒体数据,但媒体数据不可用时触发。
suspend 事件在浏览器读取媒体数据中止时触发。
timeupdate 事件在当前的播放位置发送改变时触发。
volumechange 事件在音量发生改变时触发。
waiting 事件在视频由于要播放下一帧而需要缓冲时触发。

//动画事件
animationend 该事件在 CSS 动画结束播放时触发
animationiteration 该事件在 CSS 动画重复播放时触发
animationstart 该事件在 CSS 动画开始播放时触发

//过渡事件
transitionend 该事件在 CSS 完成过渡后触发。

//其他事件
message 该事件通过或者从对象(WebSocket,Web,Event Source或子frame或父窗口)接收到消息时触发
online 该事件在浏览器开始在线工作时触发。
offline 该事件在浏览器开始离线工作时触发。
popstate 该事件在窗口的浏览历史(history 对象)发生改变时触发
show 该事件当

//元素在上下文菜单显示时触发
storage 该事件在 Web Storage(HTML 5 Web 存储)更新时触发
toggle 该事件在用户打开或关闭 元素时触发
wheel 该事件在鼠标滚轮在元素上下滚动时触发

# onclick字符串参数的解决办法

使用转义编码实现:

str='<li onclick="toParentPage(&quot;'+popoupData[i].url+'&quot;)">'+popoupData[i].title+'</li>';

# window.open

//page.html' 弹出窗口的文件名; 
//newwindow' 弹出窗口的名字(不是文件名),非必须,可用空''代替; 
//hight=100 窗口高度; 
//width=400 窗口宽度; 
//top=0 窗口距离屏幕上方的象素值; 
//left=0 窗口距离屏幕左侧的象素值; 
//toolbar=no 是否显示工具栏,yes为显示; 
//menubar,scrollbars 表示菜单栏和滚动栏。 
//resizable=no 是否允许改变窗口大小,yes为允许; 
//location=no 是否显示地址栏,yes为允许; 
//status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许;
window.open("page.html","","height=50,width=80,top=20,left=50,toolbar=no,menubar=no,
                            scrollbars=no,resizable=no,location=no,status=no");

//子页面赋值给父页面
window.opener.document.getElementByIdx('textfield').value='123123123';

# URLSearchParams

定义了一些实用的方法来处理 URL 的查询字符串

let params = new URLSearchParams("?name=chenjiang&age=24");
console.log(params.get("name")); // chenjiang

# append方法

追加一个新的参数,如果重名了也不会被覆盖

let params = new URLSearchParams("?name=chenjiang&age=24");
params.append("name", "cccjjj"); // 追加一个重名的
console.log(params.getAll('name')); // ["chenjiang","cccjjj"]

# set方法

可以修改指定名称的参数,如果设置前已经存在匹配的值,该方法会删除多余的,如果将要设置的值不存在,则创建它。

let params = new URLSearchParams("?name=chenjiang&age=24");
params.set("name", "cccjjj"); 
console.log(params.getAll('name')); // ["cccjjj"]

# delete方法

可以删除指定名称的所有搜索参数

let params = new URLSearchParams("?name=chenjiang&age=24&name=cccjjj");
params.delete("name");// 有两个name一并删除
console.log(params.getAll("name")); // []

# get方法

返回第一个与搜索参数对应的值,如果有多个同名的参数,只返回第一个

let params = new URLSearchParams("?name=chenjiang&age=24&name=cccjjj");
console.log(params.get("name")); // chenjiang
console.log(params.get("good")); // null

# getAll方法

以数组的形式返回与指定搜索参数对应的所有值

let params = new URLSearchParams("?name=chenjiang&age=24&name=cccjjj");
console.log(params.getAll('name'));  // ["chenjiang","cccjjj"]

# has方法

返回一个 Boolean 表示一个指定的键名对应的值是否存在

let params = new URLSearchParams("?name=chenjiang&age=24");
console.log(params.has("name")); // true

# forEach方法

let params = new URLSearchParams("?name=chenjiang&age=24");
params.forEach(function (value, key, searchParams) {
  console.log(value, key);
});

// 打印结果
"chenjiang" "name"
"24" "age"

# entries方法

返回一个iterator,允许遍历该对象中包含的所有键/值对

let params = new URLSearchParams("?name=chenjiang&age=24");

// 显示键/值对
for (var val of params.entries()) {
  console.log(val[0] + "---" + val[1]);
}

// 打印结果
"name---chenjiang"
"age---24"

# keys方法

返回一个iterator,遍历器允许遍历对象中包含的所有键

let params = new URLSearchParams("?name=chenjiang&age=24");

for(var key of params.keys()) {
  console.log(key);
}

// 打印结果
"name"
"age"

# values方法

返回一个iterator,该遍历器允许遍历对象中包含的所有值

let params = new URLSearchParams("?name=chenjiang&age=24");

for(var val of params.values()) {
  console.log(val);
}

// 打印结果
"chenjiang"
"24"

# iframe父子传参通信

iframe通信可以分为2种,跨域和非跨域两种。

# 非跨域 父调子

//父页面
<button class="b" id="b">点击</button>
<iframe src="a.html" name='child' id="f"></iframe>

<script>
  var ob=document.getElementById('b');
  var msg='hellow,i'm your father!!'
  ob.onclick=function(){
    if(child.document.readyState=="complete"){
      child.window.fnChild(msg); //关键
    }
  }
</script>

//子页面
<script>
 function fnChild (arg) {
  console.log(arg); //确实得到了 hellow,i'm your father!!
 }
</script>

父页面调用子页面使用 childFrameName.window.fnName();当然有一点很重要,你需要判断 iframe 里面的东西是否加载完成,如果加载未完成就调用的话是会报错的

判断iframe 加载是否完成有2种方法:

//1 
childFrameName.document.readyState=="complete"

//2 使用onload 回调函数,把调用的方法都写在这个回调函数里面
childFrameName.onload=function(){}

# 非跨域 子调父

同样的,在子页面调用父页面的方法使用 parent.window.fnName()就可以了

//在父页面
<div id="a" class="a"></div>
<iframe src="a.html" name='child' id="f"></iframe>

<script>
  function changeColor(){
    var oDiv=document.getElementById('a');
    oDiv.style.backgroundColor="red";
  }
</script>

//在子页面
<button class="ob" onclick="c()">anniu</button>
<script>
  function c(){
    parent.window.changeColor(); //关键
  }
</script>

# 非跨域 父页面获取子页面元素操作

首先,我们有几种方法拿到子页面的window对象或者doucument 对象,(还是使用上面的html)

//原生js 获取子页面window对象
var childWindow=document.getElementById("f").contentWindow;
var childWindow=document.getElementsByTagName('f')[0].contentWindow;
//其实也就是普通的获取方法,只是后面多了一个contentWindow;

//jquery
var childWindow=$('#f').contentWindow;

//获取子页面的document对象 (假设已经通过上面的方法得到了window对象)
var frameDoc=childWindow.document;
var frameBody=frameDoc.body;

//jquery 也是跟上面的一样
var frameDoc=$(childWindow.document);

//原生获取元素
//上面都已经拿到了子页面的window对象,所以获取子页面的元素也就只需要想普通操作那样获取就好
childWindow.document.getElementById('a') 
childWindow.document.getElementById('a').style.color='red' //改个颜色

//jq拿子页面元素
$('#f').contents().find('#a'); //$('#f').contents 这相当于拿到了iframe 里面所有的dom;

# 非跨域 子页面获取父页面元素

//原生js
//window.parent获取到父页面的window对象,那么接可以使用一般操作获取元素
window.parent.document.getElementById('a'); 
window.parent.document.getElementById('a').style.color="red";//dom操作

//jquery
$("#a",parent.document); //$(父页面元素选择器, parent.document);
$("#a",parent.document).css('border','1px solid red');

# 跨域 postMessage

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

//otherWindow 窗口对象
// message 传递的消息,可以是对象,可以是字符串
// target 目标窗口,* 代表所有;
otherWindow.postMessage(message, targetOrigin, [transfer]);

# 跨域 子传父

我在主页面有个透明遮罩,里面是一个iframe的登录窗口,在子页面点击关闭的时候,需要关掉父页面的这个登陆遮罩;在这里存在跨域,所以使用上面的获取元素,操作元素的方法不能够使用,这里使用postMassage

//子页面
<div id="loginBox">登录窗口</div>
<div id="close"></div>

//父页面
<div id="loginMask">
  <iframe src="子页面"></iframe>
</div>

//子页面
<script>
  let oClose=document.getElementById('#close');
  oClose.onclick=function(){
    window.parent.postMessage('close','*');
  }
</script>
//父页面
<script>
  window.addEventListener('message',function(event){
    if(event.data=='close'){
      let oLoginMask=document.getElementById('loginMask');
      oLoginMask.style.display="none";
    }
  })
</script>

# 父传子

//父页面
<button id="btn">传递消息</button>
<iframe id='f' src="子页面.html"></iframe>
//子页面
<div id="a"></div>

//父页面
<script>
  let oBtn=document.getElementById('btn');
  let oFrame=document.getElementById('f');
  oBtn.onclick=function(){
    oFrame.contentWindow.postMessage('hello','*');
  }
</script>

//子页面
<script>
  window.addEventListener('message',function(){
    if(event.data=='hello'){
      document.getElementById('#a').innerText=event.data;
    }
  })
</script>

# fetch的用法

fetch是web提供的一个可以获取异步资源的api,目前还没有被所有浏览器支持,它提供的api返回的是Promise对象,这种功能以前是使用 XMLHttpRequest 实现的

//请求的网址
var url = "http://127.0.0.1:7777/list";
//发起get请求
var promise = fetch(url).then(function(response) {

   //response.status表示响应的http状态码
   if(response.status === 200){
     //json是返回的response提供的一个方法,会把返回的json字符串反序列化成对象
	 //也被包装成一个Promise了
     return response.json();
   }else{
     return {}
   }

});
    
promise = promise.then(function(data){
  //响应的内容
	console.log(data);
}).catch(function(err){
	console.log(err);
})

# Date()的用法

var myDate = new Date(); //显示这种格式  Mar 31 10:10:43 UTC+0800 2012 
myDate.getYear(); //获取当前年份(2位) 
myDate.getFullYear(); //获取完整的年份(4位,1970-????) 
myDate.getMonth(); //获取当前月份(0-11,0代表1月)
myDate.getDate(); //获取当前日(1-31) 
myDate.getDay(); //获取当前星期X(0-6,0代表星期天) 
myDate.getTime(); //获取当前时间(从1970.1.1开始的毫秒数) 
myDate.getHours(); //获取当前小时数(0-23) 
myDate.getMinutes(); //获取当前分钟数(0-59) 
myDate.getSeconds(); //获取当前秒数(0-59) 
myDate.getMilliseconds(); //获取当前毫秒数(0-999)

myDate.toLocaleDateString(); //获取当前日期 2021/7/14
myDate.toLocaleTimeString(); //获取当前时间 2021/7/14
myDate.toLocaleString( ); //获取日期与时间  2021/7/14下午2:19:46

new Date().getTime(); //十三位的时间戳 1626244866842
new Date().valueOf(); //十三位的时间戳 1626244866842
Date.now(); //返回自1970年1月1日00:00:00 UTC以来经过的毫秒数

new Date('2021/07/14'); //正确 , Wed Jul 14 2021 00:00:00 GMT+0800 (中国标准时间)
new Date('2021,07,14'); //正确 , Wed Jul 14 2021 00:00:00 GMT+0800 (中国标准时间)
new Date(1626244866842); //正确 , Wed Jul 14 2021 14:41:06 GMT+0800 (中国标准时间)
new Date('2021-07-14'); // 错误的,这种格式是不支持的

# for循环使用await

//方式一
for( let i=0; i<array.length; i++ ){
    let datas = await getDatas()
    break
}

//方式二
for( let item of array ){
    let datas = await getDatas()
    break
}

//方式三
for await (let item of array){
    break
}