有很多朋友写 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>
事件成功触发,元素也正常打印出来了

到此我们的异步问题就解决了
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于