标签的批量增加
方法一
//在box标签下添加多个子标签
let box = document.querySelector('.box');
let str = '';
for (let i = 0; i < 10; i++) {
str += `<div class="box-child">子标签${i+1}</div>`;
}
box1.innerHTML = str;
方法二
let box = document.querySelector('.box');
// 创建一个虚拟DOM
let frag = document.createDocumentFragment();
for (let i = 0; i < 20; i++) {
let div = document.createElement("div"); //创建div标签
div.innerHTML = `子标签${i+1}`; //修改div标签
div.classList.add("box-child"); //给div标签添加类名
frag.append(div);
}
box.append(frag);
盒子模型
获取标签的宽高: content+padding+border
box . offsetWidth : 本身竞度+边框线+左右内边距:
box . offsetHeight : 本身高度+边框线+上下内边距;
获取标签的宽高:content+padding
box . clientWidth : 本身的宽度+左右内边距;
box . clientHeight : 本身的高座+上下内边距;
box . clientTop : 上边框线的宽度
box . clientLeft : 左边框线的亮度
box . scrollWidth : 盒子的实际竞度(包括滚动条不可见部分+滚动好的宽度,不包括边线)
box . scrollTHeight : 盒子的实际高度(包括滚动条不可见部分+滚动条的高度,不包括边线)
标签尺寸大小和偏移量
获取到标签的尺寸大小和偏移量
box.getBoundingClientRect
获取标签的偏移量
box . offsetTop:相对有定位属性的祖先节点上偏移量(包含父元素的padding和子元素的marigin,不含父元素margin):
box . offsetLeft:相对有定位属性的祖先节点左偏移量; .
Tips:
1.不管通过哪个方法获取到偏移量,都是相对于页面内容来的(页面没有滚动的情况)
2.通过getBoundingClientRect获取到的偏移量是不包含滚动距离,通过offsetTop offsetLeft获取到的偏移量是包含滚动距离
3.offsetTop offsetLeft:如果某个祖先有定位,那么获取到的偏移量就是相对于定位的那个祖先来的,如果祖先都没有定位,那么获取到的偏移量就是相对于页面内容来的
获取页面滚动距离
获取页面滚动距离
滚动条向下滚动的距离
document.body.scrollTop
document.documentElement.scrollTop
window.pageYOffset
滚动条向右滚动的距离
document.body.scrollLeft
document.documentElement.scrollLeft
window.pageXOffset
获取窗口宽高
window. innerHeight:浏览器窗口可见区域高度
window. innerWidth:浏览器窗口可见区域宽度
JS操作标签css样式
标签.style.属性 = 属性值
例: box.style.color = 'red';
让页面滚动到指定位置
相对于窗口滚动到指定位置,两者没有区别
window.scroll(x,y)
window.scrollTo(x,y)
相对于当前位置滚动到指定位置
window.scrollBy(x,y)
让页面滚动到对应标签
标签对象.scrollIntoView() 传入参数为布尔值 true:窗口与对应标签顶部持平 false:窗口与对应标签底部持平
事件的绑定与移除
事件的绑定
标签对象 . addEventListener(‘事件’,事件处理函数)
事件的移除
标签对象 . removeEventListener(‘事件’,事件处理函数)
鼠标点击事件的绑定与移除
let box = document.querySelector('.box');
box.onclick = function(){
alert("点了box一下");
}
box.onclick = null;
事件的绑定( 兼容IE9以下)
标签对象 . attachEvent(‘on事件’,事件处理函数);
事件的移除( 兼容IE9以下)
标签对象 . detachEvent(‘on事件’,事件处理函数);
事件的绑定与移除要考虑兼容性问题
事件绑定兼容性处理的封装
function addEvent(el,ev,fn){
if(el.addEventListener){ //判断兼容性
el.addEventListener(ev,fn);
}else if(el.attachEvent){
el.attachEvent('on'+ev,fn);
}else{
el['on'+ev] = fn;
}
}
addEvent(标签,'事件',事件处理函数);
事件移除兼容性处理的封装
function removeEvent(el,ev,fn){
if(el.removeEventListener){ //判断兼容性
el.removeEventListener(ev,fn);
}else if(el.detachEvent){
el.detachEvent('on'+ev,fn);
}else{
el['on'+ev] = null;
}
}
removeEvent(标签,'事件',事件处理函数)
事件对象
在整个事件处理过程中,会产生一个事件对象event
function 事件处理函数(){
console.log(event); //打印event得到一个事件对象PointerEvent{}
console.log(event.target); //点击的目标标签
alert("点了box一下");
}
事件对象中的部分属性
clientX clientY :获取到的是鼠标点击的位置距离窗口的左边和上边的距离
pageX pageY : 获取到的是鼠标点击的位置距离整个页面内容的左边和上边的距离
offsetX offsetY: 获取到的是鼠标点击的位置距离自身左边和上边的距离
兼容性处理
function 事件处理函数(ev){ //有些浏览器不能通过event直接获取到事件对象,需要通过传入实参
let e = ev||event;
console.log(e);
console.log(e.target);
alert("点了box一下");
}
事件三阶段
事件响应链
事件三阶段:先捕获 后目标 再冒泡
eventPhase :1 2 3
<div class="grand-parent">
<div class="parent">
<div class="son">son</div>
</div>
</div>
<script>
//获取
let son = document.querySelector('.son');
let parent = document.querySelector('.parent');
let grandParent = document.querySelector('.grand-parent');
fn(son,'click',function(){
console.log('点击了son:',event.eventPhase); //eventPhase是event的一个属性,显示当前所处的事件阶段,1表示捕获,2表示目标,3表示冒泡
});
fn(parent,'click',function(){
console.log('点击了parent:',event.eventPhase);
});
fn(grandParent,'click',function(){
console.log('点击了grandParent:',event.eventPhase);
});
//点击son标签
//执行结果: 点击了son: 2
// 点击了parent: 3
// 点击了grandParent: 3
//封装的事件函数
function fn(el,ev,fn){
if(el.addEventListener){
el.addEventListener(ev,fn);
}else if(el.attachEvent){
el.attachEvent('on'+ev,fn);
}else{
el['on'+ev] = fn;
}
}
</script>
上级标签一般在冒泡阶段执行,只有一种方法(addEventListener)让上级标签在捕获阶段执行
<div class="grand-parent">
<div class="parent">
<div class="son">son</div>
</div>
</div>
<script>
let son = document.querySelector('.son');
let parent = document.querySelector('.parent');
let grandParent = document.querySelector('.grand-parent');
son.addEventListener('click',function(){
console.log('点击了son:',event.eventPhase);
},true); //true是addEventListener()中的第三个参数。默认值为false,表示在冒泡阶段处理事件。 如果为true,则在捕获阶段处理事件。
parent.addEventListener('click',function(){
console.log('点击了parent:',event.eventPhase);
},true);
grandParent.addEventListener('click',function(){
console.log('点击了grandParent:',event.eventPhase);
},true);
//点击son标签
//执行结果: 点击了grandParent: 1
// 点击了parent: 1
// 点击了son: 2
</script>
事件委托
原理:利用了事件冒泡
又叫事件代理,事件委托就是当多个标签需要绑定相同的一个事件的时候,就可以把这个事件委托给他们的某个上级标签。
例:给每个li标签添加点击事件
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
用非事件代理实现
let LI = document.querySelectorAll('li');
LI.forEach(el=>{
el.addEventListener('click',function(){
console.log(this);
});
})
用事件代理实现
let UL = document.querySelector('ul');
UL.addEventListener('click',function(){
console.log(event.target);
})
//就是当多个标签需要绑定相同的一个事件的时候,就可以把这个事件委托给他们的某个祖先