前言:
一、常说的js(浏览器执行的js)包括两大部分
1.js基础知识是基于:ECMA 262标准,规定一些基本语法。
2.js-web-api:w3c标准。
1) W3C标准中关于JS的规定: DOM 、BOM 、事件绑定 、ajax请求 (包括http请求)、存储。 本章介绍了这5个内容!
2) W3C 标准没有规定任何JS 基础相关的东西,不管是变量类型、原型、作用域和异步。只管定义于浏览器中JS 操作页面的API 和全局变量。
二、页面弹框是window.alert(123)
浏览器需要做:
1.定义一个window全局变量,对象类型
2.给他定义一个alert属性,属性值是一个函数
一、DOM
题目:
1.DOM有哪些基本数据结构?
树(tree)
2.DOM操作有哪些常用的API?
获取DOM节点以及节点的property and Attribute 获取父节点;
获取子节点;
新增节点,删除节点
3.DOM节点的attr和property有什么区别?
属性 Property是js对象属性的修改(如var p = document.getElementById('x').className),这个className就是他的对象属性。
而Attribute是html标签属性的修改(像a标签的href),我们可以通过getAttribute和setAttribute去获得设置属性。
知识点:
1.DOM的本质
浏览器拿到html代码后,DOM把html代码结构化结构化成浏览器可识别以及js可识别的东西。 html代码就是一个字符串,但是浏览器已经把字符串机构化成树形结构了。
2.DOM节点操作
1>获取DOM节点 分元素和集合(具体API见百度)
如:
①document.getElementById("xxx");//为元素
②document.getElementsByTagName("xxx");//为集合
3.DOM结构操作
DOM 结构操作(常用)
创建节点 document.createElement(node)
获取父元素 childNode.parentElement
获取子元素 parentNode.childNodes
删除节点 parentNode.removeChild(childNode)//爸爸,消灭我吧?
添加节点parentNode.appendChild(node)//向parentNode追加node节点
注意:
childNodes 属性返回所有的节点,包括文本节点、注释节点等等;
children 属性只返回元素(标签)节点;
二、BOM(Browser Object Model)
题目:
1.如何检测浏览器的类型?
答:采用(navigator.userAgent)
var ua = navigator.userAgent var isChrome = ua.indexOf('Chrome')
附加:银屏分辨率
console.log(screen.width); console.log(screen.height);
一般建议谷歌为开发的浏览器
2.拆解url的各部分?
答:location.(href,port,protocol,pathname,search,hash)
三、事件绑定
题目:
1.编写一个通用的事件监听函数?
见知识点2
2.描述事件冒泡流程?
1>DOM树形结构
2>事件冒泡
3>阻止冒泡
4>冒泡的应用
3.对于一个无线下拉加载图片的页面,如何给每个图片绑定事件?
使用代理
知识点:
1.通用事件绑定
标准addEventListener(type,fn,false);//ie低版本attachEvent()不考虑 移除事件绑定:
标准 removeEventListener(type,fn,false);//IE 版 detachEvent()不考虑
2.事件冒泡
从子节点往上一直逐级遍历到根结点的叫做冒泡。如果除当前节点外的父节点也添加了事件,那么点击当前节点时,父节点也会跟着反应。所以我们可以在当前节点内添加阻止冒泡e.stopPropatation()事件,防止其他父级节点事件也跟着反应。
<div id="div1"> <p id="p1">激活</p> <p id="p2">取消</p> <p id="p3">取消</p> <p id="p4">取消</p> </div> <div id="div2"> <p id="p5">取消</p> <p id="p6">取消</p> </div> <script> // 事件冒泡 // 从子节点往上一直逐级遍历到根结点的叫做冒泡,如果除当前节点外的其他节点也添加了事件,那么点击当前节点时,其他节点也会跟着反应,所以我们可以在当前节点内添加阻止冒泡事件,防止其他父级节点事件也跟着反应 var p1 = document.getElementById('p1'); var body = document.body // p1.addEventListener("click",function(e){ // e.stopPropagation();//阻止冒泡 // alert('激活'); // }) // body.addEventListener("click",function(e){ // alert('取消'); // }) function bindEvent(elem,type,fn){ elem.addEventListener(type,fn); } bindEvent(p1,'click',function(e){ e.stopPropagation(); alert('激活') }) bindEvent(body,'click',function(e){ alert('激活') }) </script>
3.代理
本来加在子元素身上的事件(普通浏览器用e.target,老的IE浏览器不考虑),加在了其父级身上。这样子就可以不用使用循环为子元素添加事件了(代码简洁)、减少浏览器内存占用。
var div1 = document.getElementById("div1"); div1.addEventListener("click",function(e){ var target = e.target; if(target.nodeName === "A"){ alert(target.innerHTML); } })
附加:事件与代理放在一起写
<div id="div1">
<a href="http://www.baidu.com" id="link1">imooc.com</a>
<a href="http://www.baidu.com" id="link2">imooc.com</a>
<a href="http://www.baidu.com" id="link3">imooc.com</a>
<a href="http://www.baidu.com" id="link4">imooc.com</a>
<p id="p1">激活</p>
<p id="p2">取消</p>
</div>
<div id="div2">
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<script>
function bindEvent(elem,type,selector,fn){
//参数的唯一性,selector和fn都是函数,如果是代理则有4个参数,如果不是代理则是3个参数
if(fn == null){
fn = selector;
selector = null;//把selector函数传给fn,并且selector为空(则减少一个函数)
}
elem.addEventListener(type,function(e){
var target;
if(selector){
//代理
target = e.target;
if(target.matches(selector)){
//如果匹配到了selector,则把对象到target(也就是子元素),selector是字符串选择器
fn.call(target,e)//匹配到了则要指向子元素对象
}
}else{
//不是代理
fn(e)
}
})
}
//代理
var div1 = document.getElementById("div1");
bindEvent(div1,'click','a',function(e){
e.preventDefault();
console.log(this.innerHTML);
})
var p1 = document.getElementById("p1");
bindEvent(p1,'click',function(e){
console.log(p1.innerHTML);
})
</script>
四、ajax
题目:
1.手写编写一个ajax,不依赖第三方库?
var xhr = new XMLHttpRequest()
xhr.open("GET","/test1.php",true)
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
alert(xhr.responseText)
}
}
}
xhr.send(null)
2.跨域的几种实现方式(他的原理)?
知识点:
1.XMLHttpRequest
//前端向后端发送get方式 var xhr = new XMLHttpRequest(); xhr.open("GET","./test1.php?name=Hansen&age=18",true); xhr.send();
//前端向后端发送POST方式 var xhr = new XMLHttpRequest(); xhr.open('POST','./test.php'); xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8"); xhr.send("name=Hansen&age=18");
//前端向后端请求数据 var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ console.log(xhr.responseText); } } } xhr.open("GET","test1.php"); xhr.send(); //test.php <?php $arr = array('name' => 'Hansen','age'=>18); echo json_encode($arr) ?>
注意:json中
将字符串转化为json对象 则var obj = JSON.parse(str);
将json对象转为str字符串 则 var str = JSON.stringify(obj);
2.状态码(readyState)与(status)
3.跨域
除了三个标签能跨域外,我们还可以使用JSONP和设置请求头进行跨域
1>什么是跨域
浏览器有同源策略,不允许ajax访问其他域的接口
跨域条件:协议、域名、端口有一个不同就算跨域
附加1:可以跨域的三个标签
①<img src="xxx">
②<link href="xxx">
③<script src="xxx">
附加2:以上三个跨域标签的应用场景
①<img>用于打点统计,统计网站可能是其他域。
②<link href=xxxx>和<script>,CDN,CDN可以是其他域名。
③<script src=xxx>,可以用于JSONP去实现跨域(见2JSONP实现原理)
2>JSONP实现原理
JSONP实现跨域,要用script标签去请求一个外域的api,返回的是一个js的callback片段,正好是自己定义的callback函数。
<script> function fn(data){ console.log(data) } </script> <script src="./test2.php"></script> //test2.php <?php $arr = array('name' => 'Hansen','age'=>18); echo 'fn(\''.json_encode($arr).'\')'; ?>
3>服务器端设置http header
header('Access-Control-Allow-Origin:*');//在php或者jsp等后端语言中设置请求头进行跨域
五、存储(cookie,sessionStorage,localStorage)
1.cookie:本身用于客户端和服务端通信,具有本地存储功能,于是就被借用,使用document.cookie = ....获取和修改即可,存储量太小,只有 4kb,所有http请求都带着,会影响获取资源的效率。
2.localStorage和sessionStorage --最大容量5M,只能存储字符串 --注意点:IOS safari 隐藏模式下,localStorage.getItem会报错,建议统一使用try-catch封装。
cookie sessionStorage localStorage的区别
1、容量(cookie存储最大4KB,localStorage存储最大5MB)
2、是否会携带到ajax中(cookie每次都会在请求中携带,localStorage存储在本地)
3、API易用性(cookie需要自己封装API,localStorage可以直接通过setItem(key,value)/getItem(key)调用)
4.localStorage存在本地,浏览器关闭依然存在。而sessionStorage浏览器关闭,sessionStorage消失。
代码:
localStorage的:
<textarea name=""id="ta" cols="30" rows="10">dasd</textarea>
<input type="button" id="btn" value="提交">
<script>
window.onload = function(){
var ta = document.getElementById('ta');
if(localStorage.text){
ta.value = localStorage.text;
//第一次是空的,当第二次输入时候判断为true
}
btn.onclick = function(){
// console.log(localStorage.text);
localStorage.text = ta.value;//localStorage存在本地,浏览器关闭依然存在
}
}
</script>
sessionStorage的:
<span id="count">0</span>
<button id="btn">+</button>
<script>
var num = 0;
if(sessionStorage.num){
num = sessionStorage.num;
}else{
num = 0;
}
btn.onclick = function(){
num++;
sessionStorage.num = num;//浏览器关闭,sessionStorage消失
count.innerHTML = num;
}
</script>