Web API:
BOM浏览器对象模型
,通过BOM可以操作浏览器窗口,比如弹出框,控制浏览器跳转,获取分辨率等。DOM文档对象模型
,提供一套操作页面元素的API,DOM处理可扩展标记语言,基于文档树的API,处理过程中整个文档都表示在存储器中。DOM:
var a=document.getElementById("id");
var b=document.getElementsByTagName("div");
伪数组,元素的集合HTMLCollection。var c=document.getElementsByName("name");
放在表单的标签元素需要写name属性。节点的集合Nodelist,如果获取某一项的触发事件需要c[0].onclick
。var d=document.getElementsByClassName("classname");
类选择器。var e=document.querySelector(".e");
query查询Selector选择器,H5新增,只查找返回第一个。var es=document.querySelectorAll(".e");
var texts=document.querySelectorAll
("input[type=text]");
属性选择器在IE8中都返回Nodelist集合。
console.dir(a);
打印对象,最下方就是对象类型,所有元素都派生于htmlElement
操作元素:设置元素的属性或调用元素的方法。
⑴元素的属性包含了标签对应的属性。★
元素(对象)封装标签的属性。
⑵设置元素格式btn.onclick
与对象.属性用法相同,区别是这是注册事件。当触发事件时系统自动检测调用。
⑶img.id,img.className
赋值、打印。
自定义属性:在html标签自定义属性。
⑴获取自定义属性:box.getAttribute("stuId");
也可获取标签本身具有的属性,但一般用box.id。
⑵设置(添加)自定义属性:box.setAttribute("try","value");
也可设置标签本身具有的属性。
⑶移除属性:box.removeAttribute("try");
⑷box.abc
不可以设置标签的自定义属性,但是box对象具有了abc属性。
样式操作:
⑴设置类样式:box.className="bg";
类样式赋值会覆盖其他类样式,使用box.className=box.className.replace("hide","show");
可以指定替换样式。
⑵设置style:box.style.width="200px";
获取标签的style属性中的字符串:box.style.cssText;
而标签可以直接设置table.border;box.style
不能获取id或类选择器设置的属性。
事件:btn.onclick
。
⑴事件源:this-触发事件的元素
⑵事件名称:类似click
⑶事件处理程序:类似onclick
可以在事件中注册事件。
this是什么:
⑴作为函数调用–>是window顶级对象但严格模式下是undefined。
⑵作为对象的方法调用–>是调用该方法的对象
⑶作为构造函数调用–>通过构造函数创建的对象
⑷事件处理函数中this–>触发事件的对象,事件源。当注册事件在循环中进行时必须用this代替触发元素。apply call
(?)
⑸定时器、forEach中的函数中的this是window。
⑹谁调用this就是谁。
innerText,innerHtml都是获取标签之间的内容。
获取区别:innerHtml
会把标签也获取到,而innerText
会把标签过滤掉。
设置区别:innerText如果设置的内容有标签会自动转义,innerHtml如果设置的内容有标签会解析标签,并挂载到DOM树。
注意:innerHtml不是标准的DOM属性,innerText是最早IE增加的属性,老版本firefox不支持此属性,它使用textContent
当标签属性只有一个值的情况,一般DOM元素对应的属性类型是布尔类型。只有是非两种选择,就用布尔值true,false当标记。
表单提交时如果不满足提交条件则return false
。onfocus
获取焦点,onblur
失去焦点。
当DOM树发生更改,游览器会立即渲染、重新绘制。
节点类型:
⑴元素节点document.getElementById();
nodeName
标签名称,nodeType
节点类型1,nodeValue
始终为null。
⑵属性节点:box.getAttributeNode("id");
nodeName
属性名称,nodeType
节点类型2,nodeValue
属性值。
⑶文本节点是换行留下的空白,标签之间的文本属于元素节点。nodeType
节点类型3,nodeValue
是换行符加一些空格。
⑷模拟文档树类型:先创建一个Node构造函数,然后创建每个元素节点,利用html.children.push("BODY");
⑸节点层级:
⒈父元素parentNode;
⒉子节点childNodes
,子元素children
。
第一个子节点firstChild
,第一个子元素firstElementChild
;
⒊最后一个子节点lastChild
,最后一个子元素lastElementChild
,用父节点调用。
⒋下一个兄弟节点nextSibling
,下一个兄弟元素nextElementSibling
;
⒌上一个兄弟节点previousSibling
,上一个兄弟元素previousElementSibling
。
⑹动态创建列表:★
createElement("ul");
创建一个DOM对象。
box.appendChild(ul);
往末尾追加对象。
box.insertBefore(div,fistEle);
指定插入fistEle之前。
ul.replaceChild(div,ul.children[0]);
替换子元素。
box.removeChild(li);
移除一个子元素。
innerHtml="";
移除所有子元素,不会删除元素身上的事件对应的函数,内存泄露。
使用for循环结合数组动态添加内容。
documentElement就是html标签。
DOM详细:
void关键字可以任意编写JS代码,但返回的都是undefined。
如果有循环里给元素注册事件的情况,需要在循环外定义函数,并把这个函数的函数名赋值给事件处理程序,提高性能。
动态创建元素:这两个都不用,一般用createElement。
⑴事件中使用document.write();
会把整个网页覆盖。
⑵arr.push("
");arr.push("
");
box.innerHtml=arr.join("");
效率更高,只渲染一次。
data.forEach遍历数组,参数是一个函数,这个函数有两个参数,第一个参数是数组中的元素,第二个参数是索引。
数组、集合删除一项后索引会重新排列。
所以当要删除所有子元素时将循环中div.children[0];始终设为0。
给同一个元素注册多个事件处理函数:
btn.addEventListener("click",btnClick,false);
可以冒泡或捕获。
第一个参数为事件名称,不带on;第二个参数是事件处理函数★,第三个参数是事件冒泡/事件捕获。true捕获,false冒泡。
给元素移除事件:
⑴btn.onclick=function(){this.onclick=null;};
⑵btn.addEventListener("click",btnClick,false);
function btnClick(){this.removeEventListener("click",btnClick,false);};
⑶低版本detachEvent("onclick",btnClick);
事件三个阶段(事件流):捕获,目标,冒泡。
事件捕获:一级一级向下传递。
事件目标:执行当前点击的元素的事件处理函数。
事件冒泡:一级一级向上传递。onclick。
事件委托:循环处理太麻烦所以转交给父元素处理,然后找到子元素(系统会把事件发生时的一些数据传递给事件处理函数)
ul.onclick=function(e){e.target.style.backgroundColor="red";}
e是事件对象,e.target是真正触发事件的对象li,目标对象,始终不变。
事件对象:默认是事件冒泡。
⑴e.type
获取事件名称,e.clientX
是鼠标在可视区域的位置,e.pageX
是鼠标在页面中的位置;
⑵e.eventPhase
:1是捕获阶段,2是目标阶段,3是冒泡阶段。
⑶e.currentTarget
调用事件处理函数的元素,就是冒泡的当前对象与this一样。
e.stopPropagation();
方法阻止事件冒泡。
e.preventDefault();
方法阻止默认行为。
⑷键盘事件:onkeydown
按下时触发,onkeyup
抬起时触发。e.keyCode
键盘码。
box.focus();
让元素获取焦点。
⑸e有兼容性问题,IE9之前版本不支持,使用window.event
。
BOM: 游览器的顶级对象是window。
alert();
prompt();
confirm();
onload=function(){
var box =document.getElementById("div");
}
定时器:不考虑调用,写出来就能运行;
⑴setTimeout(function(){location.href="http..."; },5000);
–> 五秒后跳转,clearTimeout是取消跳转。
⑵setInterval(function(){},1000);
间隔一段时间做一段事。
⑶setTimeout
和setInterval
里面的参数function()可以换成在外面定义的函数名
;
⑷clearInterval
和clearTimeout
可以在setTimeout和setInterval里面使用,但要给set设置变量接收返回值,如var a=setInterval(function(){clearInterval(a);},1000;);
location对象:
⑴URL统一资源定位符:scheme(协议)://host(端口):port/path(路径)?query(查询)#fragment
⑵属性:href / search / hash
⑶方法:assign();
reload();
replace();
reload(true);
会强制从服务器强制获取刷新界面如ctrl+f5,false可能会读取缓存;
assign("http..."); / replace("https...")
都是跳转,前者会记录历史,后者不会。
history对象:
history.forward(); / history.go(1);
前进;
history.back(); / history.go(-1);
后退;
navigator对象:
navigator.userAgen
t可以获取当前设备信息,在控制台的Network的Headers查看。
进程和线程:进程里有很多线程。
但却是单线程执行JavaScript代码,先执行主线程,才会考虑事件或定时器的任务
当遇到事件或定时器会放进任务队列。任务队列:先进先出。
拖拽效果:给document注册onmousedown
和onmouseup
事件。
特效:
偏移量:offsetLeft盒子左边框和左边offsetParent的距离,offsetTop盒子上边框和上面offsetParent的距离;
offsetWidth
盒子的宽度(加上内边距,边框)offsetHeight
盒子的高度(加上内边距,边框)offsetParent
一般是body,父盒子设置position后为父盒子。
onmouseover和onmouseout会触发事件冒泡,在IE中问题大,用onmouseenter
和onmouseleave
代替。
scrollHeight
和scrollWidth
用来计算滚动条滚动出去的大小,内容+padding,不包括边框。
offset需要具体问题具体分析,放大镜需要设置一元一次方程、比例和变量即是大图片移动的距离=mask移动的距离*大图片最大能移动的距离/mask最大能移动的距离
,然后设置它的style.left与top。
clientWidth
、clientWidth
不包括边框也不包括滚动出去的距离。
clientTop
、clientLeft
就是盒子边框。
this.offsetLeft(box.offsetLeft);
左偏移
this.offsetTop(box.offsetTop);
上偏移量;
动画:
计时器设置动画,动态改变定位的left或者top的值。
current=box.offsetLeft;
设置当前坐标,
step=10;步进,target=500;停止位置。
让每一个执行动画的元素记录自己的计时器。element.timerId=setInterval(fn,2);
判断之前是否有定时器,如果有则清除定时器,保证点几次都走同样的速度。
当前位置current>目标位置target则setp取负step=-Math.abs(step);当前位置与目标位置的差小于步进则将left设为目标位置,然后清除计时器。
cloneNode(true);会复制子元素,而false自会复制自身不会复制子元素。
轮播图:
⑴根据img数量动态创建列表
⑵移上显示左右图标,离开隐藏
⑶点击圆点切换对应图片
⑷点击左右剪头切换图片
⑸自动滚动
回到顶部:
⑴获取滚动出去的距离getScrollTop().scrollTop;
⑵设置一个范围判断类样式的改变。
⑶点击置顶按钮获取当前滚动出去的距离。
⑷以动画形式回到目标位置0。
面向对象:(具体)
对象是单个事物的抽象。一本书、一辆汽车、一个人、一个数据库、一张网页。
对象是一个容器,封装了属性和方法。数据集或功能集。
无序属性的集合,其属性可以包含基本值、对象或者函数。
每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。具有灵活、代码可复用、高度模块化等特点。
构造函数是构造对象的函数。p1.constructor构造器,构造函数,可以获取创建p1的类型。
构造函数中的方法会因为每次创建对象而开辟空间造成资源浪费,所以需要将方法写在外面,用Person.prototype.sayHI=function(){};
原型对象定义方法、通用属性。静态成员才是独属调用Person的。
当该对象拥有很多方法时则使用Person.prototype={a:function(){}};
当重新设置构造函数的prototype,一定要重新设置constructor属性。这是因为普通对象没有constructor,只有构造函数的原型对象才有constructor属性。
系统内置对象的构造函数都是只读的,只能增加方法或属性:Person.prototype.getSum=function(){};
每一个对象都有__proto__,都指向构造函数的prototype。
构造函数、实例、原型三者之间的关系:
构造函数中的属性Person.prototype属于原型对象,原型对象中Person.prototype.
constructor属于构造函数;构造函数new
Person()是实例对象,实例p1.__proto__属于原型对象。
原型对象中的原型对象,就是原型链。下级是Object,最早都是Person的原型。
Object.prototype===p1.proto.proto。最终是null,这是访问过程。
设置属性不关心原型链,即使原型链有test属性也直接给对象增加一个test属性p1.test=“abc”;
贪吃蛇案例:
随机生成方块:构造函数box,属性拥有backgroundColor、width、height、x、y方法有render渲染(创建设置style),random随机生成盒子位置,(地图高度除以盒子高度-1再乘以盒子高度。)
创建一个js工具对象,整个项目共享。
创建食物对象,利用自调用函数避免全局变量命名冲突,在里面让外部可以访问构造函数window.Food=Food;
创建蛇对象,render方法中新开forEach函数、定时器中的this会改变成window,设置一个值记录this。
再抽象一个对象控制游戏的逻辑。
函数是对象,拥有属性prototype,bind方法等。bind中的第一个参数可以改变函数中的this指向。
开发时分散写js,发布网站时合并成一个js文件。
存在多个自调用函数而前一个没写分号作为结尾则会报错,所以一定要在自调用函数前面加分号。
自调用函数的形参和实参都会传入window和undefined。可以压缩形参变量名,老版本游览器undefined可以被重新赋值,所以传入undefined防止被改变。
继承:
原型继承问题:不会使用★
⑴修改原型属性一定要修改constructor
。
Student.prototype=Person.prototype;
Student.prototype.constructor=Student;
⑵属性是通过原型继承的,原型上的成员都是共享的、无法设置构造函数的参数。
借用构造函数继承:
在Student中调用Person.call(this,name,age);
改变Person的this指向。
组合继承:原型继承+借用构造函数。
在新版本的游览器中可以根据条件声明函数,新版本游览器在条件语句中定义函数不会进行函数提升。老版本ie中,条件语句中定义函数会进行函数。提升。
fn.apply(o,[1,2]);
第二个参数是数组,是传入fn的实参,第一个参数是需要改变成的this。
Array.prototype.splice.call(obj,1,2);
Array.prototype.push.call(obj,15);
删除对象的的name:delete o.name;
delete obj[“0”];括号里是属性名。
函数的成员:
fn.name
函数名称,fn.length
形参个数;
fn.arguments
获取实参;arguments私有成员、可变参数,fn.arguments.callee
当前函数;fn.caller
调用fn的函数。
高阶函数:函数作为参数或返回值。
animate(callback);
forEach(fn);setInterval(fn,50);
addEventListener("click",fn,false);
arr.sort(fn);
function getFun(type){
return function(obj){
return Object.prototype.toString.call(obj) === type;
}}
var isArray=getFun("[object Array]");
var arr=[];isArray(arr);