代码入下:
function addGlobalStyle(css) {
var head, style
head = document.getElementsByTagName('head')[0]
if (!head) {
return
}
style = document.createElement('style')
style.innerHTML = css
head.appendChild(style)
}
function removeNodeInsertedListener(bindedFunc) {
var eventTypeList = ['animationstart', 'webkitAnimationStart', 'MSAnimationStart', 'oAnimationStart']
eventTypeList.forEach(function (eventType) {
document.removeEventListener(eventType, bindedFunc, false)
})
}
function addNodeInsertedListener(elCssPath, handler, executeOnce, noStyle) {
var animName = 'anilanim'
var prefixList = ['-o-', '-ms-', '-khtml-', '-moz-', '-webkit-', '']
var eventTypeList = ['animationstart', 'webkitAnimationStart', 'MSAnimationStart', 'oAnimationStart']
if (!noStyle) {
var css = elCssPath + '{'
var css2 = ''
prefixList.forEach(function (prefix) {
css += prefix + 'animation-duration:.001s;' + prefix + 'animation-name:' + animName + ';'
css2 += '@' + prefix + 'keyframes ' + animName + '{from{opacity:.9;}to{opacity:1;}}'
})
css += '}' + css2
addGlobalStyle(css)
}
if (handler) {
var bindedFunc = e => {
var els = document.querySelectorAll(elCssPath)
var tar = e.target
// var match = false
if (els.length !== 0) {
els.forEach(function (el) {
if (tar === el) {
if (executeOnce) {
removeNodeInsertedListener(bindedFunc)
}
handler.call(tar, e)
return
}
})
}
}
eventTypeList.forEach(function (eventType) {
document.addEventListener(eventType, bindedFunc, false)
})
return bindedFunc
}
}
调用方式:
addNodeInsertedListener('.some-class', function(e) {
// do something
// e.target 为目标元素
console.log($(e.target))
})
实现思路
- 通过 css 选择器, 为需要监听的元素动态添加一个动画效果
- 监听全局的
animationstart
事件 - 监听到
animationstart
事件后, 比对目标元素是否在监听的元素里 - 如果在, 则触发回调
缺点
功能比较单一, 就是只能监听目标元素的插入(原本就存在也可), 由于是使用的监听动画的方式, 对于目标元素里的子元素发生变化, 并不会触发
优点
只要触发了回调, 肯定是你需要的目标元素, 不会出现大量乱七八糟的元素, 让你去做筛选
用在?
比如为微博写个插件, 监听下微博列表, 过滤掉一些你不想看的微博