针对于在视图外部的的动画的停止
1.选择对应的事件
我开始想选择的事件是scroll事件,来获取目标元素所在高度和监听页面的滑动高度来判读元素的动画是否停止渲染 ,但是细想了一下,scroll事件中添加多个判断会影响用户体验。然后询问其他大佬,找到了另一个API 是 IntersectionObserver
2.了解和使用API
在使用IntersectionObserver创建实例的时候 提供了一种异步观察目标元素的交点的变化与一个祖先元素或具有顶级文档的视口。祖先元素或视口称为根(在我而言就是相当于 目标DOM元素 和 创建的视图实例 监听他们接触的情况),以下面代码为例
//创建视图
var Observer = new IntersectionObserver(回调函数 [,options ]);
//监听获取到的DOM元素
let DOM = doucment.
intersectionObserver.observe(DOM);
我们可以在options中配置创建的视图的大小
未定义的化 var Observer = new IntersectionObserver(回调函数)
视图即使全屏
参数 | 模拟值 | 意义 |
---|---|---|
root | root: document.querySelector(’#scrollArea’) | 可以传入DOM元素 |
rootMargin | rootMargin: ‘0px’, | 和css的margin差不多定义视图的margin |
threshold | threshold: 0.0 | 在0.0到1.0之间的单个数字或数字数组中,指定观察对象的相交区域与总边界框区域之比默认为0.0 |
//但是我们没有用到options 如下是我们定义的代码
function clearAnimation(el, isChildren = false, childrenName) {
// 通过传入的字符串来获取含有动画的目标函数或者 含有动画的目标函数的父元素
let arrList = $(el);
// 获取元素css兼容ie
function getCss(obj, attribute) {
if (obj.currentStyle) { //ie兼容
return obj.currentStyle[attribute];
}
else {
return window.getComputedStyle(obj, null)[attribute];
}
}
// 判断是否有子元素
if (isChildren) {
// 获取想要的子元素
function getChildrenDiv(children, liObj) {
//遍历子元素,当元素是DIV时,返回这个元素
for (var i = 0; i < children.length; i++) {
if (children[i].nodeName == liObj.toUpperCase()) {
var liChildrenDiv = children[i];
return liChildrenDiv;
}
}
}
//
let BigAnimation = "";
// 监听元素所处位置
var intersectionObserver = new IntersectionObserver(function (entries) {
// 获取到想要取消动画的子元素
let elementS = getChildrenDiv(entries[0].target.children, childrenName)
// console.log(elementS)
let animation01 = ""
if (!BigAnimation) {
if (getCss(elementS, "animation").length <= 37) {
return false
}
animation01 = getCss(elementS, "animation");
} else {
animation01 = BigAnimation;
}
// 当元素所处在视图中
if (entries[0].isIntersecting) {
elementS.style.animation = animation01;
}
// 当元素所出与视图外面
else {
new Promise((resolve, reject) => {
BigAnimation = getCss(elementS, "animation");
resolve('成功')
}).then((res) => {
elementS.style.animation = "none";
})
}
});
}
// 没有子元素
else {
let BigAnimation2 = "";
var intersectionObserver = new IntersectionObserver(function (entries) {
// 获取到想要取消动画的子元素
let elementS = entries[0].target
// console.log(elementS)
let animation01 = ""
if (!BigAnimation2) {
//当动画为none 的时候获取到的
if (getCss(elementS, "animation").length <= 37) {
return false
}
animation01 = getCss(elementS, "animation");
} else {
animation01 = BigAnimation2;
}
// 当元素所处在视图中
if (entries[0].isIntersecting) {
elementS.style.animation = animation01;
}
// 当元素所出与视图外面
else {
new Promise((resolve, reject) => {
BigAnimation2 = getCss(elementS, "animation");
resolve('成功')
}).then((res) => {
elementS.style.animation = "none";
})
}
});
}
//
arrList.each((index, item) => {
intersectionObserver.observe(item);
})
}
//父元素是 .botton_hand 子元素有动画 子元素是div
Event.interSectionObserver(".botton_hand", true, "div")
Event.interSectionObserver(".animation_btn")
参数 | 数据类型 | 必须输入? | 默认值 | 代表意义 |
---|---|---|---|---|
参数 el | string | 是 | 所选元素的字符串 像使用$()方法 一样传入实参 | |
参数 isChildren | boolean | 否 | false | 想要去除的动画在子元素上么 默认不在子元素, 若有 传入true |
参数 childrenName | string | 否 | 子元素的名称 |
进一步优化点
1.可以不替换css动画,用移除和添加class来达到 渲染对应的样式
2.可以用于图片的渲染以达到懒加载