Offset
offsetWidth和offsetHight
检测盒子自身宽高+padding+border。
这两个属性,他们绑定在了所有的节点元素上。获取之后,只要调用这两个属性,我们就能够获取元素节点的宽和高。
offset宽/高 = 盒子自身的宽/高 + padding +border;
offsetWidth = width+padding+border;
offsetHeight = Height+padding+border;
offsetLeft和offsetTop
检测距离父盒子有定位的左/上面的距离。
返回距离上级盒子(带有定位)左边s的位置,如果父级都没有定位则以body为准,offsetLeft 从父亲的padding 开始算,父亲的border 不算。在父盒子有定位的情况下,offsetLeft == style.left(去掉px)。
offsetParent
检测父系盒子中带有定位的父盒子节点。
1、返回改对象的父级 (带有定位)
如果当前元素的父级元素没有进行CSS定位(position为absolute或 relative,fixed),offsetParent为body。
2、如果当前元素的父级元素中有CSS定位(position为absolute或relative,fixed),offsetParent取最近的那个父级元素。
offsetLeft和style.left区别
一、最大区别在于offsetLeft可以返回没有定位盒子的距离左侧的位置。
而 style.left不可以
二、offsetTop 返回的是数字,而 style.top 返回的是字符串,除了数字外还带有单位:px。
三、offsetTop 只读,而 style.top 可读写。(只读是获取值,可写是赋值)
四、如果没有给 HTML 元素指定过 top 样式,则style.top 返回的是空字符串。
缓动动画
原理
leader=leader+(target-leader)/10;
盒子位置 = 盒子本身位置+(目标位置-盒子本身位置)/ 10;
动画原理 = 盒子位置 + 步长(步长越来越小)。
offsetLeft和style.left的值的获取问题
offsetLeft获取盒子距离左侧具有定位的父盒子的距离(没有的body),四舍五入取整。
Style.left获取的是具体值。
案例
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
left: 0;
}
</style>
</head>
<body>
<button>运动到200</button>
<button>运动到400</button>
<div></div>
<script>
var btn = document.getElementsByTagName("button");
var div = document.getElementsByTagName("div")[0];
//运动到200
btn[0].onclick = function () {
animate(div,200);
}
//运动到400
btn[1].onclick = function () {
animate(div,400);
}
//封装缓动动画
function animate(ele,target) {
//先清定时器
clearInterval(ele.timer);
//定义定时器
ele.timer = setInterval(function () {
//获取步长,步长应该是越来越小
var step = (target - ele.offsetLeft)/10;
//大于0向上取整,小于0向下取整
step = step>0 ? Math.ceil(step) : Math.floor(step);
//动画原理: 目标位置 = 当前位置 + 步长
ele.style.left = ele.offsetLeft + step + "px";
//检测缓动动画有没有停止
if(Math.abs(target - ele.offsetLeft) <= Math.abs(step)){
//处理小数赋值
ele.style.left = target + "px";
clearInterval(ele.timer);
}
},30);
}
</script>
</body>
</html>
Scroll
scrollWidth和scrollHeight
检测盒子的宽高,不包括border。调用者:节点元素、属性。盒子内容的宽高。(如果有内容超出了,显示内容的高度)。
兼容性:IE567可以比盒子小。IE8+火狐谷歌不能比盒子小。
scrollWidth和scrollHeight不包括border和margin
scrollWidth = width + padding;
scrollTop和scrollLeft
网页,被浏览器遮挡的头部和左边部分。
兼容性:
一、未声明 DTD(谷歌只认识他)
document.body.scrollTop
二、已经声明DTD(IE678只认识他)
document.documentElement.scrollTop
三、火狐/谷歌/ie9+以上支持的
window.pageYOffset
只要页面滚动无论向左向右,向上向下,哪怕只有1px,都会触动onscroll事件。
window.onscroll = function () {
//兼容写法
document.title = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || 0;
}
获取title、body、head、html标签
document.title — 文档标题;
document.head — 文档的头标签
document.body — 文档的body标签;
document.documentElement — 文档的html标签;html标签并不是通过document.html去访问的;
json的遍历
//json
var json = {"aaa":11,"bbb":22};
//遍历
for(var k in json){
console.log(k); //属性
console.log(json[k]); //值
}
//compatMode属性,CSS1Compat
alert(document.compatMode);
//获取key为aaa的值
alert(json.aaa);
Scroll()的封装
判断页面有没有DTD约束:
document.compatMode === "BackCompat"
BackCompat 未声明
CSS1Compat 已经声明
// 封装scroll
function scroll() {
if(window.pageYOffset != null) { // ie9+ 高版本浏览器
// 因为 window.pageYOffset 默认的是 0 所以这里需要判断
return {
left: window.pageXOffset,
top: window.pageYOffset
}
}
else if(document.compatMode === "CSS1Compat") { // 标准浏览器 来判断有没有声明DTD
return {
left: document.documentElement.scrollLeft,
top: document.documentElement.scrollTop
}
}
return { // 未声明 DTD
left: document.body.scrollLeft,
top: document.body.scrollTop
}
}
function scroll(){
//简单封装
return {
"top": window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
"left": window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft
}
}
ScrollTo
window.scrollTo ,屏幕跳转,方法可把内容滚动到指定的坐标。
语法:
scrollTo(xpos,ypos)
xpos 必需,要在窗口文档显示区左上角显示的文档的 x 坐标。
ypos 必需,要在窗口文档显示区左上角显示的文档的 y 坐标。
案例
案例一
需求:1、当我们滚动界面的时候,被卷曲的头部超过第二个盒子距离顶部的位置,那么直接给第二个盒子加类名.fixed;2、当我们滚动界面的时候,被卷曲的头部小于第二个盒子距离顶部的位置,那么直接给第二个盒子取消类名.fixed
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0
}
img {
vertical-align: top;
}
.main {
margin: 0 auto;
width: 1000px;
margin-top: 10px;
}
#Q-nav1 {
overflow: hidden;
}
.fixed {
position: fixed;
top: 0;
left: 0;
}
</style>
<!--引入工具js-->
<script src="my.js"></script>
<script>
window.onload = function () {
//1.获取对象
var topDiv = document.getElementById("top");
var height = topDiv.offsetHeight;
var middle = document.getElementById("Q-nav1");
var main = document.getElementById("main");
//2.卷起
window.onscroll = function () {
//判断被卷起的头部的大小
if(scroll().top > height){
//3.满足条件添加类,否则删除类
middle.className += " fixed";
//第二个盒子不占位置,给第三个盒子一个上padding占位置,不出现盒子抖动问题
main.style.paddingTop = middle.offsetHeight + "px";
}else {
middle.className = "";
//清零
main.style.paddingTop = 0;
}
}
}
</script>
</head>
<body>
<div class="top" id="top">
<img src="images/top.png" alt=""/>
</div>
<div id="Q-nav1">
<img src="images/nav.png" alt=""/>
</div>
<div class="main" id="main">
<img src="images/main.png" alt=""/>
</div>
</body>
</html>
案例二
需求:屏幕滚动多少,两侧的图片联动向下移动等距离。
window.onload = function () {
var imgArr = document.getElementsByTagName("img");
window.onscroll = function () {
//获取被卷去的头部的值
var val = scroll().top;
//移动两个盒子(缓动移动)
animate(imgArr[0],val+80); //80是图片的高度
animate(imgArr[1],val+80);
}
}
案例三
需求:浏览器被卷去的头部超过1000显示小火箭,然后点击小火箭屏幕缓慢移动到最顶端。
window.onload = function () {
//1.获取图片
var img = document.getElementsByTagName("img")[0];
window.onscroll = function () {
//被卷去的距离大于1000显示小火箭,否则隐藏
2.显示隐藏小火箭
if(scroll().top>1000){
img.style.display = "block";
}else{
img.style.display = "none";
}
//每次移动滚动条的时候都给leader赋值,模拟leader获取距离顶部的距离
leader = scroll().top;
}
//3.缓动跳转到页面最顶端(利用我们的缓动动画)
var timer = null;
var target = 0; //目标位置
var leader = 0; //显示区域自身的位置
img.onclick = function () {
//要用定时器,先清定时器
clearInterval(timer);
timer = setInterval(function () {
//获取步长
var step = (target-leader)/10;
//处理步长
step = step>0?Math.ceil(step):Math.floor(step);
leader = leader +step;
//显示区域移动
// window.scrollTo(x,y);浏览器显示区域跳转到指定的坐标
window.scrollTo(0,leader);
//清除定时器
if(leader === 0){
clearInterval(timer);
}
},25);
}
}
案例4
需求:点击ol中的li,屏幕滑动到对应的ul中的li的范围。
技术点:
盒子属性:auto:适应盒子自身的宽度或者高度。
盒子属性:100%:适应盒子父盒子的宽度或者高度。
100%子盒子会继承父盒子的宽高。父盒子继承body宽高。Body继承html的宽高。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
body,html {
height: 100%;
}
ul {
list-style: none;
height: 100%;
}
ul li {
height: 100%;
}
ol {
list-style: none;
position: fixed;
top: 80px;
left: 50px;
}
ol li {
width: 50px;
height: 50px;
border: 1px solid #000;
text-align: center;
line-height: 50px;
margin-top: -1px;
cursor: pointer;
}
</style>
</head>
<body>
<ul>
<li>鞋子区域</li>
<li>袜子区域</li>
<li>裤子区域</li>
<li>裙子区域</li>
<li>帽子区域</li>
</ul>
<ol>
<li>鞋子</li>
<li>袜子</li>
<li>裤子</li>
<li>裙子</li>
<li>帽子</li>
</ol>
<script src="animate.js"></script>
<script>
//0.获取元素
var ul = document.getElementsByTagName("ul")[0];
var ol = document.getElementsByTagName("ol")[0];
var ulLiArr = ul.children;
var olLiArr = ol.children;
var target = 0;var leader = 0;var timer = null;
//1.指定ul和ol中的li的背景色,对应的li背景色相同
//设置一个数组,里面装颜色,然指定的颜色给数组中的指定元素
var arrColor = ["pink","blue","yellow","orange","green"];
//利用for循环给两个数组的元素上色
for(var i=0;i<arrColor.length;i++){
//上色
ulLiArr[i].style.backgroundColor = arrColor[i];
olLiArr[i].style.backgroundColor = arrColor[i];
//属性绑定索引值
olLiArr[i].index = i;
//2.老三步。(并绑定事件)循环绑定,为每一个li绑定点击事件
olLiArr[i].onclick = function () {
//***获取目标位置
//获取索引值。
target = ulLiArr[this.index].offsetTop;
//要用定时器,先清除定时器
clearInterval(timer);
//3.利用缓动动画原理实现屏幕滑动
timer = setInterval(function () {
//(1).获取步长
var step = (target-leader)/10;
//(2).二次处理步长
step = step>0?Math.ceil(step):Math.floor(step);
//(3).屏幕滑动
leader = leader + step;
window.scrollTo(0,leader);
//(4).清除定时器
if(Math.abs(target-leader)<=Math.abs(step)){
window.scrollTo(0,target);
clearInterval(timer);
}
},25);
}
}
//4.用scroll事件模拟盒子距离最顶端的距离。
window.onscroll = function () {
//每次屏幕滑动,把屏幕卷去的头部赋值给leader,模拟获取显示区域距离顶部的距离
leader = scroll().top;
}
</script>
</body>
</html>
事件对象(event)
再触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持event对象,但支持的方式不同。普通浏览器支持 event(带参,任意参数),ie 678 支持 window.event(无参,内置)。
事件对象的获取(event的获取)
IE678中,window.event,在火狐谷歌中,event或者,在事件绑定的函数中,加参,这个参数就是event。
获取事件的兼容方式
- 不写参数直接使用event;
- 写参数,但是为event….var,(主要用这种)
event = event || window.event;
事件属性
screenX、pageX和clientX的区别
- PageY/pageX: 鼠标位于整个网页页面的顶部和左侧部分的距离。(页面)
- ScreenY/screenX: 鼠标位于屏幕的上方和左侧的距离。(屏幕)
- ClientX/clientY: 鼠标位于浏览器的左侧和顶部的距离。(浏览器大小和位置)
PageY和pageX的兼容写法
在页面位置就等于 = 看得见的+看不见的
pageY/pageX=event.clientY/clientX+scroll().top/scroll().left
onmousemove
onmousemove事件会在鼠标指针移动时发生。
案例
1、需求:当鼠标进入图片,出现细节图。鼠标放到小盒子上,让大盒子里面的图片和我们同步等比例移动。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 350px;
height: 350px;
margin:100px;
border: 1px solid #ccc;
position: relative;
}
.big {
width: 400px;
height: 400px;
position: absolute;
top: 0;
left: 360px;
border: 1px solid #ccc;
overflow: hidden;
display: none;
}
.mask {
width: 175px;
height: 175px;
background: rgba(255, 255, 0, 0.4);
position: absolute;
top: 0;
left: 0;
cursor: move;
display: none;
}
.small {
position: relative;
}
img {
vertical-align: top;
}
</style>
<script src="animate.js"></script>
<script>
window.onload = function () {
//技术点:onmouseenter==onmouseover 前者不支持冒泡
//技术点:onmouseleave==onmouseout 前者不支持冒泡
//0.获取相关元素
var box = document.getElementsByClassName("box")[0];
var small = box.firstElementChild || box.firstChild;
var big = box.children[1];
var mask = small.children[1];
var bigImg = big.children[0];
//1.鼠标放上去显示盒子,移开隐藏盒子。(为小盒子绑定事件)
small.onmouseenter = function () {
//封装好方法调用:显示元素
show(mask);
show(big);
}
small.onmouseleave = function () {
//封装好方法调用:隐藏元素
hide(mask);
hide(big);
}
//2.黄盒子跟随移动
//绑定的事件是onmousemove,而事件源是small(只要在小盒子上移动1像素,黄盒子也要跟随)
small.onmousemove = function (event) {
//想移动黄盒子,必须知道鼠标在small中的位置。x作为mask的left值,y作mask的top值。
event = event || window.event;
var pagex = event.pageX || scroll().left + event.clientX;
var pagey = event.pageY || scroll().top + event.clientY;
//让鼠标在黄盒子最中间,减去黄盒子宽高的一半
var x = pagex - box.offsetLeft - mask.offsetWidth/2;
var y = pagey - box.offsetTop - mask.offsetHeight/2;
//限制换盒子的范围
//left取值为大于0,小盒子的宽-mask的宽。
if(x<0){
x = 0;
}
if(x>small.offsetWidth-mask.offsetWidth){
x = small.offsetWidth-mask.offsetWidth;
}
//top同理。
if(y<0){
y = 0;
}
if(y>small.offsetHeight-mask.offsetHeight){
y = small.offsetHeight-mask.offsetHeight;
}
//移动黄盒子
console.log(small.offsetHeight);
mask.style.left = x + "px";
mask.style.top = y + "px";
//3.右侧的大图片,等比例移动。
//如何移动大图片?等比例移动。
// 大图片/大盒子 = 小图片/mask盒子
// 大图片走的距离/mask走的距离 = (大图片-大盒子)/(小图片-黄盒子)
// var bili = (bigImg.offsetWidth-big.offsetWidth)/(small.offsetWidth-mask.offsetWidth);
//大图片走的距离/mask盒子都的距离 = 大图片/小图片
var bili = bigImg.offsetWidth/small.offsetWidth;
var xx = bili*x;
var yy = bili*y;
bigImg.style.marginTop = -yy+"px";
bigImg.style.marginLeft = -xx+"px";
}
}
</script>
</head>
<body>
<div class="box">
<div class="small">
<img src="images/001.jpg" alt=""/>
<div class="mask"></div>
</div>
<div class="big">
<img src="images/0001.jpg" alt=""/>
</div>
</div>
</body>
</html>
2、需求:在指定位置按住鼠标左键移动对话框。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.nav {
height: 30px;
background: #036663;
border-bottom: 1px solid #369;
line-height: 30px;
padding-left: 30px;
}
.nav a {
color: #fff;
text-align: center;
font-size: 14px;
text-decoration: none;
}
.d-box {
width: 400px;
height: 300px;
border: 5px solid #eee;
box-shadow: 2px 2px 2px 2px #666;
position: absolute;
top: 40%;
left: 40%;
}
.hd {
width: 100%;
height: 25px;
background-color: #7c9299;
border-bottom: 1px solid #369;
line-height: 25px;
color: white;
cursor: move;
}
#box_close {
float: right;
cursor: pointer;
}
</style>
<script src="animate.js"></script>
<script>
window.onload = function () {
//分析:鼠标按下,触动事件,移动在更换对话框的位置。
//鼠标按下onmousedown 鼠标弹起:onmouseup 鼠标移动onmousemove
var box = document.getElementById("d_box");
var drop = document.getElementById("drop");
//先按下,在移动触动此事件
drop.onmousedown = function (event) {
//获取鼠标在盒子中的坐标,将来移动的时候减去保证鼠标在盒子的指定位置
event = event || window.event;
var pagex = event.pageX || scroll().left + event.clientX;
var pagey = event.pageY || scroll().top + event.clientY;
var x = pagex - box.offsetLeft;
var y = pagey - box.offsetTop;
document.onmousemove = function (event) {
//2.把鼠标的坐标赋值给对话框。
event = event || window.event;
var xx = event.pageX || scroll().left + event.clientX;
var yy = event.pageY || scroll().top + event.clientY;
//二次操作鼠标位置 减去鼠标在盒子中的坐标
xx = xx - x;
yy = yy - y;
//给box赋值
box.style.left = xx+"px";
box.style.top = yy+"px";
//禁止文本选中(选中后取消)
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
//事件解绑
drop.onmouseup = function () {
//解绑
document.onmousemove = null;
}
}
</script>
</head>
<body>
<!--顶部注册部分,无用-->
<div class="nav">
<a href="javascript:;" id="register">注册信息</a>
</div>
<!--我们移动的对话框-->
<div class="d-box" id="d_box">
<div class="hd" id="drop">
<i>注册信息 (可以拖拽)</i>
<span id="box_close">【关闭】</span>
</div>
<div class="bd"></div>
</div>
</body>
</html>
3、需求:模拟滚动条,鼠标拖动滚动条,滚动条动,而且内容等比例联动。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 300px;
height: 500px;
border: 1px solid red;
margin: 50px auto;
overflow: hidden;
position: relative;
}
.scroll {
width: 20px;
height: 530px;
background-color: #ccc;
position: absolute;
top: 0;
right: 0;
}
.bar {
width: 20px;
background-color: red;
border-radius: 10px;
cursor: pointer;
position: absolute;
top: 0;
}
.content {
padding: 15px;
}
</style>
<script src="animate.js"></script>
<script>
window.onload = function () {
//步骤:
//1.根据内容和盒子的比例确定bar的高。
//2.绑定事件(鼠标按下,然后移动)
//3.鼠标移动,bar联动
//4.内容等比例联动
//0.获取相关元素
var box = document.getElementById("box");
var content = box.children[0];
var scroll = box.children[1];
var bar = scroll.children[0];
//1.根据内容和盒子的比例确定bar的高。
//内容的高/盒子的高 = scroll的高/bar的高
//bar的高 = 盒子的高*scroll的高/内容的高
var barHeight = box.offsetHeight*scroll.offsetHeight/content.offsetHeight;
bar.style.height = barHeight + "px";
//2.绑定事件(鼠标按下,然后移动)
bar.onmousedown = function (event) {
event = event || window.event;
var pageyy = event.pageY || scroll().top + event.clientY;
var y = pageyy - bar.offsetTop;
//模拟拖拽案例
document.onmousemove = function (event) {
//获取鼠标在页面的位置。
event = event || window.event;
var pagey = event.pageY || scroll().top + event.clientY;
//鼠标的位置-鼠标在盒子中的位置。
pagey = pagey - y;
//限制y的取值。大于0,小于scroll的高度-bar的高度
if(pagey<0){
pagey = 0;
}
if(pagey>scroll.offsetHeight-bar.offsetHeight){
pagey = scroll.offsetHeight-bar.offsetHeight;
}
//3.鼠标移动,bar联动
bar.style.top = pagey + "px";
//4.内容等比例联动
//高级比例: 内容走的距离/bar走的距离 = (内容的高-大盒子的高)/(scroll的高-bar的高)
var s = pagey *(content.offsetHeight-box.offsetHeight)/(scroll.offsetHeight-bar.offsetHeight);
//s赋值给content。通过marginTop负值移动content
content.style.marginTop = -s+"px";
//让被选文字清除。
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}
}
//事件解绑
document.onmouseup = function () {
document.onmousemove = null;
}
}
</script>
</head>
<body>
<div class="box" id="box">
<div class="content">
JavaScript脚本语言具有以下特点:<br>
(1)脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。<br>
(2)基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。<br>
(3)简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。<br>
(4)动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。<br>
(5)跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提上机器上的浏览器支 持JavaScript脚本语言,目前JavaScript已被大多数的浏览器所支持。<br>
不同于服务器端脚本语言,例如PHP与ASP,JavaScript主要被作为客户端脚本语言在用户的浏览器上运行,不需要服务器的支持。所以在早期程序员比较青睐于JavaScript以减少对服务器的负担,而与此同时也带来另一个问题:安全性。
而随着服务器的强壮,虽然程序员更喜欢运行于服务端的脚本以保证安全,但JavaScript仍然以其跨平台、容易上手等优势大行其道。同时,有些特殊功能(如AJAX)必须依赖Javascript在客户端进行支持。随着引擎如V8和框架如Node.js的发展,及其事件驱动及异步IO等特性,JavaScript逐渐被用来编写服务器端程序。<br>
</div>
<div class="scroll">
<div class="bar"></div>
</div>
</div>
</body>
</html>
Client
clientWidth & clientHeight
clientWidth 获取网页可视区域宽度
clientHeight 获取网页可视区域高度
两种用法,调用者不同,意义不同:
- 盒子调用: 指盒子本身。
- body/html调用: 可视区域大小。
clientX & clientY
clientX 鼠标距离可视区域左侧距离(event调用)
clientY 鼠标距离可视区域上侧距离(event调用)
clientTop & clientLeft
clientTop和clientLeft分别表示盒子的border宽和高。
Offset、ScrollTo、Client 总结
Width和height
- clientWidth = width + padding
- clientHeight = height + padding
- offsetWidth = width + padding + border
- offsetHeight = height + padding + border
- scrollWidth = 内容宽度(不包含border)
- scrollHeight = 内容高度(不包含border)
top和left
- offsetTop/offsetLeft :
- 调用者:任意元素。(盒子为主)
- 作用:距离父系盒子中带有定位的距离。
- scrollTop/scrollLeft:(盒子也可以调用,必须有滚动条)
- 调用者:document.body.scrollTop/…..(window)
- 作用:浏览器无法显示的部分(被卷去的部分)。
- clientY/clientX:(clientTop/clientLeft 值的是border)
- 调用者:event.clientX(event)
- 作用:鼠标距离浏览器可视区域的距离(左、上)。
Client检浏览器宽/高度(可视区域)
//获取屏幕可视区域的宽高
function client(){
if(window.innerHeight !== undefined){
return {
"width": window.innerWidth,
"height": window.innerHeight
}
}else if(document.compatMode === "CSS1Compat"){
return {
"width": document.documentElement.clientWidth,
"height": document.documentElement.clientHeight
}
}else{
return {
"width": document.body.clientWidth,
"height": document.body.clientHeight
}
}
}
Onresize事件
浏览器的大小改变时触发。
事件总结
区分:
1. window.onscroll 屏幕滑动
2. window.onresize 浏览器大小变化
3. window.onload 页面加载完毕
4. div.onmousemove 鼠标在盒子上移动
5. onmouseup/onmousedown == onclick
获得屏幕宽高
分辨率是屏幕图像的精密度,指显示器所能显示的像素有多少。
window.screen.width
冒泡
事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;这个事件从原始元素开始一直冒泡到DOM树的最上层。
冒泡:子元素事件被触动,父盒子的同样的事件也会被触动。
取消冒泡就是取消这种机制。
阻止冒泡
- w3c的方法是:(火狐、谷歌、IE11)
event.stopPropagation()
- IE10以下则是使用:
event.cancelBubble = true
兼容写法
//阻止冒泡
event = event || window.event;
if(event && event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
addEventListenner
addEventListenner(参数1,参数2,参数3)方法用来绑定事件。
- 调用者是:事件源。
- 参数1:事件去掉on
- 参数2 :调用的函数
- 参数3:可有可无。没有默认false.false情况下,支持冒泡。True支持捕获。
案例
1、需求:点击登录按钮,显示模态框。点击出去login以外的所有盒子隐藏模态框。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body,html {
height: 100%;
padding: 0;
margin: 0;
}
.mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: none;
background: rgba(0, 0, 0, 0.6);
}
.login {
width: 400px;
height: 300px;
cursor: pointer;
background-color: #fff;
margin: 200px auto;
}
</style>
</head>
<body>
<div class="mask">
<div class="login" id="login"></div>
</div>
<a href="#">注册</a>
<a href="#">登陆</a>
<script src="jquery1.0.0.1.js"></script>
<script>
//1.给登录绑定事件
var mask = document.getElementsByClassName("mask")[0];
var a = document.getElementsByTagName("a")[1];
a.onclick = function (event) {
//显示模态框
show(mask);
//阻止冒泡
event = event || window.event;
if(event && event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
}
//2.给document绑定事件,因为可以冒泡,只要判断,点击的不是login,那么隐藏模态框
document.onclick = function (event) {
//获取点击按钮后传递过来的值。
event = event || window.event;
//兼容获取事件触动时,被传递过来的对象
var aaa = event.target?event.target:event.srcElement;
console.log(event.target);
//判断目标值的ID是否等于login,如果等于不隐藏盒子,否则隐藏盒子。
if(aaa.id !== "login"){
mask.style.display = "none";
}
}
</script>
</body>
</html>
事件委托
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
//普通的事件绑定,没有办法为新创建的元素绑定事件。所以我们要使用冒泡的特性,事件委托
ul.onclick = function (event) {
//获取事件触动的时候传递过来的值
event = event || window.event;
var aaa = event.target?event.target:event.srcElement;
//判断标签名,如果是li标签弹窗
if(aaa.tagName === "LI"){
alert("我是li");
}
}
缓动框架
获取任意类型的CSS样式的属性值
Div.style.width
div.currentStyle.width
Window.getComputedStyle(div,null).width;
他们的公共使用变量或者字符串获取属性值的方法都是:去电属性和点,然后加上中括号和属性的字符串形式。
var div = document.getElementsByTagName("div")[0];
console.log(getStyle(div,"padding"));
console.log(getStyle(div,"background-color"));
//兼容方法获取元素样式
function getStyle(ele,attr){
if(window.getComputedStyle){
return window.getComputedStyle(ele,null)[attr];
}
return ele.currentStyle[attr];
}
开闭原则
定义一个变量。数据可以修改。但是,只能修改成为两个值。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
div {
position: absolute;
top: 40px;
left: 10px;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<button>运动到400</button>
<div></div>
<script>
var btnArr = document.getElementsByTagName("button");
var div = document.getElementsByTagName("div")[0];
btnArr[0].onclick = function () {
var json = {"left":10,"top":200,"width":300,"height":200};
animate(div,json);
}
//参数变为3个
function animate(ele,json){
//先清定时器
clearInterval(ele.timer);
ele.timer = setInterval(function () {
//开闭原则
var bool = true;
//遍历属性和值,分别单独处理json
//attr == k(键) target == json[k](值)
for(var k in json){
//四部
var leader = parseInt(getStyle(ele,k)) || 0;
//1.获取步长
var step = (json[k] - leader)/10;
//2.二次加工步长
step = step>0?Math.ceil(step):Math.floor(step);
leader = leader + step;
//3.赋值
ele.style[k] = leader + "px";
//4.清除定时器
//判断: 目标值和当前值的差大于步长,就不能跳出循环
//不考虑小数的情况:目标位置和当前位置不相等,就不能清除清除定时器。
if(json[k] !== leader){
bool = false;
}
}
//只有所有的属性都到了指定位置,bool值才不会变成false;
if(bool){
clearInterval(ele.timer);
}
},25);
}
//兼容方法获取元素样式
function getStyle(ele,attr){
if(window.getComputedStyle){
return window.getComputedStyle(ele,null)[attr];
}
return ele.currentStyle[attr];
}
</script>
</body>
</html>
回调函数
程序执行完毕,在次执行的函数。
在函数中给指定的函数定义一个形参,然后程序执行到最后,调用这个形参后面加一个括号。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
div {
position: absolute;
top: 40px;
left: 10px;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<button>运动到400然后回来</button>
<div></div>
<script>
var btnArr = document.getElementsByTagName("button");
var div = document.getElementsByTagName("div")[0];
btnArr[0].onclick = function () {
var json1 = {"left":300,"top":200,"width":300,"height":200};
var json2 = {"left":10,"top":30,"width":100,"height":100};
animate(div,json1, function () {
animate(div,json2, function () {
animate(div,json1);
});
});
}
//参数变为3个
function animate(ele,json,fn){
//先清定时器
clearInterval(ele.timer);
ele.timer = setInterval(function () {
//开闭原则
var bool = true;
//遍历属性和值,分别单独处理json
//attr == k(键) target == json[k](值)
for(var k in json){
//四部
var leader = parseInt(getStyle(ele,k)) || 0;
//1.获取步长
var step = (json[k] - leader)/10;
//2.二次加工步长
step = step>0?Math.ceil(step):Math.floor(step);
leader = leader + step;
//3.赋值
ele.style[k] = leader + "px";
//4.清除定时器
//判断: 目标值和当前值的差大于步长,就不能跳出循环
//不考虑小数的情况:目标位置和当前位置不相等,就不能清除清除定时器。
if(json[k] !== leader){
bool = false;
}
}
//只有所有的属性都到了指定位置,bool值才不会变成false;
if(bool){
clearInterval(ele.timer);
//所有程序执行完毕了,现在可以执行回调函数了
//只有传递了回调函数,才能执行
if(fn){
fn();
}
}
},25);
}
//兼容方法获取元素样式
function getStyle(ele,attr){
if(window.getComputedStyle){
return window.getComputedStyle(ele,null)[attr];
}
return ele.currentStyle[attr];
}
</script>
</body>
</html>
案例
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>旋转木马轮播图</title>
<link rel="stylesheet" href="css/css.css"/>
<script src="js/jquery1.0.0.1.js"></script>
<script src="js/js.js"></script>
</head>
<body>
<div class="wrap" id="wrap">
<div class="slide" id="slide">
<ul>
<!--五张图片-->
<li><a href="#"><img src="images/slidepic1.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic2.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic3.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic4.jpg" alt=""/></a></li>
<li><a href="#"><img src="images/slidepic5.jpg" alt=""/></a></li>
</ul>
<!--左右切换按钮-->
<div class="arrow" id="arrow">
<a href="javascript:;" class="prev"></a>
<a href="javascript:;" class="next"></a>
</div>
</div>
</div>
</body>
</html>
window.onload = function () {
var arr = [
{ // 1
width:400,
top:70,
left:50,
opacity:20,
zIndex:2
},
{ // 2
width:600,
top:120,
left:0,
opacity:80,
zIndex:3
},
{ // 3
width:800,
top:100,
left:200,
opacity:100,
zIndex:4
},
{ // 4
width:600,
top:120,
left:600,
opacity:80,
zIndex:3
},
{ //5
width:400,
top:70,
left:750,
opacity:20,
zIndex:2
}
];
//0.获取元素
var slide = document.getElementById("slide");
var liArr = slide.getElementsByTagName("li");
var arrow = slide.children[1];
var arrowChildren = arrow.children;
//设置一个开闭原则变量,点击以后修改这个值。
var flag = true;
//1.鼠标放到轮播图上,两侧的按钮显示,移开隐藏。
slide.onmouseenter = function () {
//arrow.style.opacity = 1;
animate(arrow,{"opacity":100});
}
slide.onmouseleave = function () {
//arrow.style.opacity = 1;
animate(arrow,{"opacity":0});
}
move();
//3.把两侧按钮绑定事件。(调用同一个方法,只有一个参数,true为正向旋转,false为反向旋转)
arrowChildren[0].onclick = function () {
if(flag){
flag = false;
move(true);
}
}
arrowChildren[1].onclick = function () {
if(flag){
flag = false;
move(false);
}
}
//4.move函数
function move(bool){
//判断:如果等于undefined,那么就不执行这两个if语句
if(bool === true || bool === false){
if(bool){
arr.unshift(arr.pop());
}else{
arr.push(arr.shift());
}
}
//在次为页面上的所有li赋值属性,利用缓动框架
for(var i=0;i<liArr.length;i++){
animate(liArr[i],arr[i], function () {
flag = true;
});
}
}
}