这段jQuery代码是如何实现的?

目的:点击div时展开/折叠ul
问题:展开时元素的height数值是从哪里获取的?

HTML结构如下:

<li>
    <div></div>
    <ul>

    </ul>
</li>

jQuery代码如下

$("div").click(function() {
        var li = $(this).parent(),//获取父元素li
        ul = li.find("ul"),//获取ul(要折叠/展开的部分)
        height = ul.height();//获取高度(未展开时应该为0)
        ul.data("data-height") || ul.data("data-height", height),//写入数据,ul.data("data-height")此时返回undefined(false),因此将height===0的数据写入ul.data("data-height")
        ul.is(":visible") ? ul.animate({//动画流程:如果visible,折叠到高度0并隐藏
            height: "0px"
        },
        230,
        function() {
            ul.hide()
        }) : (ul.show(), ul.css({//否则先显示,再设置高度为0,再展开
            height: "0px"
        }), ul.animate({
            height: ul.data("data-height") + "px"//这里有问题,"data-height"此时的数据应该为0,为何ul还能正常展开?
        },
        230)
        );

求教!!!

阅读 3k
5 个回答

好了,我看过你的问题了,为啥不是:

$('div').click(function() {
    var is_hide = !1;
    if($(this).data('is_hide') != undefined) {
        is_hide = $(this).data('is_hide');
    }
    is_hide ? ($(this).next('ul').slideUp(),$(this).data('is_hide',!0)) : ($(this).next('ul').slideDown(),$(this).data('is_hide',!1));
});

以上是我觉得应该的代码逻辑,下面给你分析一下代码

$("div").click(function() {
        var li = $(this).parent(),//获取父元素li
        ul = li.find("ul"),//获取ul(要折叠/展开的部分)
        height = ul.height();//获取高度(未展开时应该为0)
        // ul.data("data-height") || ul.data("data-height", height);//这里的目的是利用jquery的data方式设置一个data-height的属性,属性值为获取到的height,但是我觉得这个代码有问题,其实应该这样更简洁:
        ul.data("height",height) || ul.data("height",height); // $.data建议参考jquery的$.data
        // ul.data("data-height") //此时返回undefined(false),因此将height===0的数据写入ul.data("data-height");

        ul.is(":visible") ? ul.animate({//动画流程:如果visible,折叠到高度0并隐藏,这里我没用过,不知道啥意思
            height: "0px"
        },
        230,
        function() {
            ul.hide()
        }) : (ul.show(), ul.css({//否则先显示,再设置高度为0,再展开
            height: "0px"
        }), ul.animate({
            height: ul.data("height") + "px"//这里有问题,"data-height"此时的数据应该为0,为何ul还能正常展开?回答:这里一次是设置div本身元素的高度,就是前面的height : '0px',但在这个地方,他是利用data获取到设置的height高度,所以在此处做展开,与元素本身的高度无关
        },
        230)
        );

注释有错误。

ul.data("data-height") || ul.data("data-height", height)这个,当第一次点击时,ul是有高度的。这时把ul的height写入到了data-height中。

所以,从头到尾,data-height都不为0,这本来就是用来记录ul的高度的。

我一开始也这样想……后来调试了下,发现height的确自始至终都是0……这是折叠状态下点击调试

clipboard.png

clipboard.png

另外元素的style属性指示的height也为0

clipboard.png

奇怪的是此时ul.data获取了正确的高度!

clipboard.png

这是展开状态下点击调试,一切正常

clipboard.png

那么折叠状态下的高度到底是怎么获得的?

新手上路,请多包涵

问题:展开时元素的height数值是从哪里获取的?
答:你自己保存的。解释详见下文。
问题:"data-height"此时的数据应该为0,为何ul还能正常展开?
答:明明可以加打印看看是不是0的,我猜不是0.我只验证了奇怪的 a || b , c ? d : e。。。。。。

解释详情:
因为你jquery代码第五行末尾用错符号了(解释见备注2),应该用分号,但是直接改分号还是有坑(解释见备注1)。主管可以扣你这个月的奖金了。洗洗睡了

备注1、注意 ul.data("data-height") || ul.data("data-height", height); 的使用,当data-height被你设置成非0之后,下次|| 右边就再也进不去了。

备注2、给你一段代码,你可以测试下,当aa为true的时候(如果初始ul有高度,那就是你第二次以及以后点击的时候。如果初始ul没有高度,大概是第三次点击以及以后), console.log('aa') 就再也不会执行了(就是再也不会更改存放数据的data-height了)。

var aa = true;
//aa = false;
aa || console.log('aa'),
console.log('bb') ? console.log('cc'):console.log('dd');

代码最后少了一个)}; XD 被我发现了。。。

补充:

其实最重要的代码是这句
ul.data("data-height") || ul.data("data-height", height),

图片描述

图片描述

所以说ul.data("data-height") 在执行完一次后,一直存储着ul的height

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题