Javascript学习笔记
Js获取元素的样式
使用Element.Style 和 Window.getComputedStyle
Element.Style语法
1
2
3
4
5let element = document.getElementById("myElement")
console.log(element.style.width) //获取元素的宽
element.style.backgroundColor = //设置元素的背景颜色
element.style.getPropertyValue('margin') //使用getPropertyValue获取元素margin
element.style.transform = `translateX(${move}px)` //设置元素的属性注意: element.style该方法只能设置和修改内联样式,也就是说如果内联样式没有设置width的话,是无法获取到width的,也无法获取实时的width
Window.getComputedStyle语法
1
2let element = document.getElementById("myElement")
let style = window.getComputedStyle(element,null).width注意: 使用getComputedStyle可以在任何情况获取到元素的样式属性,但是却无法修改,如果需要修改只能使用style
js的事件委派
作用: 解决多次绑定事件的性能问题,以及解决新添加的元素绑定的事件无效的问题。(实现是利用冒泡)
原生javascript的事件委派
语法
1
2
3
4
5
6
7
8<ul id="ul">
<li>则是li1</li>
<li>则是li2</li>
<li>则是li3</li>
<li>则是li4</li>
<li>则是li5</li>
</ul>
<button>点我添加li</button>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30window.onload = function(){
let ul = document.getElementById("ul")
/*
为ul绑定click事件,委派到里面的li
其中利用(event.target)
*/
//方法1:
ul.addEventListener('click', function(event){
//判断event.target是否为li,如果为li再做操作
if(event.target.tagName == 'li'){
event.target.style.color = 'red'
}
})
//方法2:
ul.onclick = function(event){
//判断event.target是否为li,如果为li再做操作
if(event.target.tagName == 'li'){
event.target.style.color = 'red'
}
}
//即使新添加的元素也还是可以绑定到事件
let button = document.getElementsByTagName("button")[0]
button.onclick = function(){
let li = document.createElement("li")
li.innerHtml = "新添加的li"
ul.appendChild(li)
}
}
使用jquery实现事件委派
语法
1
2
3
4
5
6
7
8<ul id="ul">
<li>则是li1</li>
<li>则是li2</li>
<li>则是li3</li>
<li>则是li4</li>
<li>则是li5</li>
</ul>
<button>点我添加li</button>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16$(document).ready(function () {
//这里我们将事件委派document中,当点击ul里的li时才触发事件
$(document).on('click', '#ul li', function (event) {
$(this).css("color", 'red')
})
//这里是没有使用事件委派的,新添加的li将无法绑定click事件
$("li").on("click", function () {
$(this).css("color", 'red')
})
$("button").click(function () {
$('#ul').append("<li>新添加的li</li>")
})
})
监听window窗口size的元素的size变化
window.resize实现
相比新的ResizeObserver API,window.resize性能更差,建议使用ResizeObserver
语法
1
2//监听window窗口的缩放或者改变大小
window.addEventListener('resize',function(){...})vue监听window.resize改变main的translateX案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//监听窗口改变大小 实时改变label的left
const container = this.$refs.container;
const main = this.$refs.main;
window.addEventListener("resize", function () {
let mainWidth = main.clientWidth;
let containerWidth = container.clientWidth;
let moveWidth = containerWidth - mainWidth;
if (mainWidth >= containerWidth) {
console.log("超过");
this.$set(
this.mainStyle,
"transform",
`translateX(${moveWidth}px)`
);
} else {
this.$set(this.mainStyle, "transform", `translateX(0)`);
}
});ResizeObserver API实现
这个方法接受一个参数,即需要监听的元素 element。当元素的尺寸发生变化时,ResizeObserver 会触发回调函数,并将 ResizeObserverEntry 对象作为参数传入。
语法
1
2
3
4
5
6
7
8
9
10let element = document.getElementById("#myElement")
const resizeObserver = new ResizeObserver((entries)=>{
for(let entry of entries){
console.log('Element:', entry.target) //元素的标签名
console.log('Width:', entry.contentRect.width) //元素的宽
}
})
//使用方法,监听element元素的长度变化
resizeObserver.observer(element)vue案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const container = this.$refs.container;
const main = this.$refs.main;
var observer = new ResizeObserver((entries) => {
for (let entry of entries) {
// console.log(entry);
let mainWidth = main.clientWidth;
let labelWidth = entry.contentRect.width;
let moveWidth = labelWidth - mainWidth;
if (mainWidth >= labelWidth) {
console.log(moveWidth);
this.$set(
this.mainStyle,
"transform",
`translateX(${moveWidth}px)`
);
} else {
this.$set(this.mainStyle, "transform", `translateX(0)`);
}
}
});
observer.observe(container);两个方法
disconnect()
方法取消对所有Element
的监听1
2
3btn.addEventListener('click', () => {
resizeObserver.disconnect();
})unobserve(target)
方法结束对指定Element的监听1
2const element = this.$refs.main;
resizeObserver.unobserve(element)
几个注意的点以及遇到的问题
在vue的mounted中使用
在组件的生命周期中,mounted钩子函数可能会被多次调用,导致多次创建Observer实例,进而造成了重复输出。你可以在mounted钩子函数中判断Observer实例是否已经被创建,如果已经被创建,就不再进行重复创建。
简单来说:
- 如果在vue中的mounted中使用,最好使用使用
this
来定义ResizeObserver
实例. - 在mounted中创建的
ResizeObserver
实例,最好在beforeDestroy
生命周期钩子中销毁:这样可以保证在vue开发时,修改程序保存之后,vue热重载之后出现多次调用1
2
3
4beforeDestroy() {
this.containerObserver.disconnect();
this.containerObserver = null;
}ResizeObserver
的问题。原因可能是因为重载时,mounted会执行一遍之前的实例,之后再创建新的实例,具体原因不明。
获取元素到视口的距离
getBoundingClientRect()
Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。
- 语法
1
2
3var element = document.querySelector("div")
var rect = element.getBoundingClientRect()
console.log(rect.top) //获取元素到视口的top距离
Javascript学习笔记
http://example.com/2023/02/01/Javascript学习笔记/