有很多朋友写 jQuery 时发现自己的方法没有错但是传递过来的值怎么打印都是 undefined (不得不说这是一件很恶心的事)
那么你的代码可能写得和下面列子有相似的毛病
拿上篇递归的列子来举例,但这次我这么写
<html>
<body>
<div class="container">
<div class="a1">
<div class="a2">
<div class="a3" onclick="handleClick(this)">
.....
</div>
</div>
</div>
</div>
<div class="container">
<div class="b1">
<div class="b2">
<div class="b3" onclick="handleClick(this)">
.....
</div>
</div>
</div>
</div>
</body>
</html>
我还是想给类名为"a3"的元素添加点击事件,一样改变父节点类名为"container"元素的背景
<script>
var handleClick = function(elem) {
var container = findElem(elem)
//顺便打印一下元素
console.log(container)
container.css({
'background-color': '#000000'
})
}
var findElem = function(elem) {
//当传入元素类名不等于container的时候
if($(elem)[0].className != "container") {
//将该元素的所有父节点传入此方法
findElem($(elem).parent())
}else {
//如果元素类名等于"container"返回该元素
return $(elem)
}
}
</script>
控制台又打印 undefined 了 很气我的方法明明没问题😠
这里我用我的想法来为大家解释一下,大家都知道 javascript 是从上到下执行的 这里我们用 findElem 方法来返回寻找到的元素,但是 findElem 方法需要一遍一遍递归它不是与 handleClick 方法同步的,所以 handleClick 等不及了 没等到 findElem 返回元素就打印了 所以这里打印了 undefined
那我们该如何解决呢?
这里就涉及到了异步的问题,jQuery 替我们封装了一个方法叫做 $.Deferred(),它起了一个延期的作用,我们这么写
<script>
//定义一个全局变量
var container
var handleClick = function(elem) {
//当findElem方法完成后
$.when(findElem(elem)).done(function() {
//改变"container"的背景颜色
container.css({
'background-color': '#000000'
})
//顺便打印一下元素
console.log(container)
})
}
var findElem = function(elem) {
var dtd = $.Deferred()
//当传入元素类名不等于container的时候
if($(elem)[0].className != "container") {
//将该元素的所有父节点传入此方法
findElem($(elem).parent())
}else {
//如果元素类名等于"container"返回该元素
container = $(elem)
dtd.resolve()
return dtd.promise()
}
dtd.resolve()
return dtd.promise()
}
</script>
事件成功触发,元素也正常打印出来了
到此我们的异步问题就解决了
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于