bom即为浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象,核心对象是windows,windows是最大的,所以BOM包含DOM
等页面加载完再执行的事件,包含页面dom元素,即整个dom树加载完毕。所以不存在命名调用的顺序。
DOMConteneLoaded是DOM元素加载完毕,不包含图片,flash等就可以执行,速度更快
窗口大小发生像素变化,就会触发该事件,即有些页面放大缩小就会改变样式。
一般用来完成响应式布局。windo.innerWidth获取当前屏幕的宽度
案例:缩小窗口隐藏ul
var ul = document.querySelector('ul');
window.addEventListener('resize',function(){
if(window.innerWidth<1000){
ul.style.display = 'none';
}else{
ul.style.display = 'block';
}
})
有多个定时器要其不同的名字,做不同的标识符
setTimeout()和setInterval()的用法与区别:
视情况而用不同定时器。
案例1:倒计时效果。在3个span中显示倒计时。(用到了之前的时间戳)
var span = document.querySelectorAll('span');
var inputTime = +new Date('2021-4-7 14:10:00');//目标时间
countDown();//先调用一次函数,避免调用定时器前出现的间隙,因为调用定时器也需要时间。
setInterval(countDown,1000);
function countDown(){
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000;//倒计时的秒数 h
var h = parseInt(times / 60 /60%24);//时
h = h < 10? '0' + h : h;
span[0].innerHTML = h;
var m = parseInt(times / 60 %60);//分
m = m < 10? '0' + m : m;
span[1].innerHTML = m;
var s = parseInt(times %60);//秒
s = s < 10? '0' + s : s;
span[2].innerHTML = s;
}
案例2:模拟显示短时间内不能再次发送短信。如60s内发送验证码则需要倒计时60s。
var btn = document.querySelector('button')
var time = 10//定义剩下的秒数
btn.addEventListener('click',function(){
btn.disabled = true;
var timer= setInterval(function(){
if(time ==0){
clearInterval(timer)
btn.disabled = false;
btn.innerHTML = '发送验证码'
time=10//重置倒计时
}else{
btn.innerHTML = '还剩下'+ time +'s';
time--
}
},1000);
})
这里很巧妙地让秒数递减,再用定时器逐秒显示,就不用将整个倒计时用定时器做。
this指向问题: 定时器里的this指向的是window,定时器算window地一个属性,其他的都指向调用者。
执行机制:
先执行同步任务,异步任务(回调函数)放入任务队列,再执行在任务队列中任务,回调函数都属于异步任务,因为回调函数需要时间,如果时间较长,会影响后面的任务
console.log(1);
setTimeout(function(){
console.log(3);
},0)
console.log(2);
//输出为1 2 3
案例:按键定时跳转其他页面,综合运用了前面刚学的倒计时配合location
<body>
<button>跳转button>
<div>div>
body>
<script>
var btn = document.querySelector("button");
var div = document.querySelector("div");
var time = 5;
btn.addEventListener("click", function () {
setInterval(function () {
if (time == 0) {
location.href = "http://www.baidu.com";
} else {
div.innerHTML = "还剩" + time + "s进入新页面";
time--;
}
}, 1000);
});
script>
案例2:提交表单跳转页面,输入英文名,跳转另一个欢迎界面
<form action="index.html">
<input type="text" name="uname" id="">
<button>跳转button>
form>
//主页面
//跳转后的页面
<div>div>
<script>
//location.search得到的是?uname=...,要先用substr去掉问好
var params = location.search.substr(1)
//再利用=把字符串分割为数组
var arr = params.split('=');
var div = document.querySelector('div')
div.innerHTML = arr[1] + ',欢迎你'
script>
表单form中的action属性,是向何处提交数据,即数据去向的地址
<script>
var fa = document.querySelector('.fa')
var son = document.querySelector('.son')
console.log(fa.offsetTop);
console.log(son.offsetLeft);
//这个显示的是距离网页边框的距离,因为这个已带定位的父亲为准,如果父亲没有定位,则以浏览器为准
console.log(son.offsetWeight)
//得到元素大小,包含内外边距和边框,height同理
console.log(son.offsetParent)
//返回带有定位的父亲,否则返回body
案例:获取鼠标在盒子内的坐标
用鼠标在页面中的坐标减去盒子的在页面中的距离
var fa = document.querySelector('.fa')
fa.addEventListener('mousemove',function(e){
var x = e.pageX - this.offsetLeft
var y = e.pageY - this.offsetTop
this.innerHTML = '这个点坐标为'+x+y;
})
案例:模拟拖动模态框,点击相应按键才显示,且可拖拽
<body>
<div class="btn">
<p>点击出现拖拽框</p>
</div>
<div class="login">
<input type="text" />
<input type="text" />
<button>关闭</button>
</div>
<div class="bg"></div>
</body>
var btn = document.querySelector(".btn");
var login = document.querySelector(".login");
var bg = document.querySelector(".bg");
var close = document.querySelector("button");
btn.addEventListener("click", function () {
bg.style.display = "block";
login.style.display = "block";
});
close.addEventListener("click", function () {
bg.style.display = "none";
login.style.display = "none";
});
login.addEventListener('mousedown',function(e){
// 获取鼠标在框内的坐标
var x = e.pageX - this.offsetLeft
var y = e.pageY - this.offsetTop +60//使得鼠标在login盒子中间
//鼠标移动到的距离减去距离盒子的距离,就是盒子的坐标
document.addEventListener('mousemove',move)
function move (e){
login.style.left =e.pageX - x +'px'
login.style.top =e.pageY - y +'px'
}
// 鼠标弹起,移除移动事件
document.addEventListener('mouseup',function(){
document.removeEventListener('mousemove',move)
})
})
</script>
该案例比较综合,用了偏移量结合之前的随鼠标移动实现拖曳,还有很多细节,比如控制拖曳时鼠标应对应哪个板块,即目标框不会突然闪烁跳动。
今日经典案例:模拟京东图片放大镜,即鼠标移动会形成一个放大镜,在隔壁放大显示图形。
<style>
* {
padding: 0;
margin: 0;
}
.old,
.old img {
width: 300px;
height: 300px;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background-color: rgb(184, 184, 92);
opacity: 0.5;
cursor: move;
pointer-events: none;
}
.show {
display: none;
position: relative;
overflow: hidden;
left: 300px;
top: -200px;
z-index: 999;
width: 450px;
height: 450px;
}
.showImg{
position: absolute;
top: 0;
left: 0%;
width: 750px;
height: 750px;
}
style>
head>
<body>
<div class="old">
<img src="微信图片_20200831202623.jpg" alt="" />
div>
<div class="mask">div>
<div class="show">
<img
src="微信图片_20200831202623.jpg" alt="" class="showImg"/>
div>
body>
<script>
var old = document.querySelector(".old");
var mask = document.querySelector(".mask");
var show = document.querySelector(".show");
var bigPic = show.querySelector('img')
// 显示隐藏
old.addEventListener("mouseover", function () {
mask.style.display = "block";
show.style.display = "block";
});
old.addEventListener("mouseout", function () {
mask.style.display = "none";
show.style.display = "none";
});
// 遮挡层拖动
old.addEventListener("mousemove", function (e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// 超出框则停在边上
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
if (maskX < 0) {
maskX = 0;
} else if (maskX>=old.offsetWidth - mask.offsetWidth) {
maskX = old.offsetWidth - mask.offsetWidth;
}
if (maskY < 0) {
maskY = 0;
} else if (maskY>=old.offsetHeight - mask.offsetHeight) {
maskY = 200;
}
// else if是为了判断在右侧和下侧时的停止条件,因为只能以左上为参照,所以要算停止距离
// 最大移动距离:盒子宽度减去遮挡层宽度
mask.style.left = maskX + "px";
mask.style.top = maskY + "px";
//大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层最大移动距离
//大图片最大移动距离
var bigMax = bigPic.offsetWidth - show.offsetWidth;
var bigX = maskX * bigMax/(old.offsetHeight - mask.offsetHeight)
var bigY = maskY * bigMax/(old.offsetHeight - mask.offsetHeight)
// 镜像移动,所以要负号
bigPic.style.left = -bigX + 'px'
bigPic.style.top = -bigY + 'px'
});
script>
整个案例细节很多