遇到了一个优点复杂的问题,希望老师耐心解答

遇到了一个优点复杂的问题,希望老师耐心解答

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
        /*css reset*/
/*清除内外边距*/
body, h1, h2, h3, h4, h5, h6, p, hr, /*结构元素*/
    ul, ol, li, dl, dt, dd, /*列表元素*/
    form, fieldset, legend, input, button, select, textarea, /*表单元素*/
    th, td, /*表格元素*/
    pre {
  padding: 0;
  margin: 0;
}

/*重置默认样式*/
body,
button,
input,
select,
textarea {
  /*font: 12px/1 微软雅黑, Tahoma, Helvetica, Arial, 宋体, sans-serif;*/
  color: #333;
  font: 12px/1 "Microsoft YaHei", Tahoma, Helvetica, Arial, SimSun, sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: 100%;
  font-weight: normal;
}
em,
i {
  font-style: normal;
}

a {
  text-decoration: none;
}
li {
  list-style-type: none;
  vertical-align: top;
}
img {
  border: none;
  /*display: block;*/
  vertical-align: top;
}
textarea {
  overflow: auto;
  resize: none;
}
table {
  border-spacing: 0;
  border-collapse: collapse;
}

/*常用公共样式*/
.fl {
  float: left;
  /* display: inline; */
}
.fr {
  float: right;
  /* display: inline; */
}
.cf:before,
.cf:after {
  content: " ";
  display: table;
}
.cf:after {
  clear: both;
}
.cf {
  *zoom: 1;
}
/* 默认样式 */
.fade {
  visibility: hidden !important;
  opacity: 0 !important;
}
.transition {
  -o-transition: all 0.5s;
  -ms-transition: all 0.5s;
  -moz-transition: all 0.5s;
  -webkit-transition: all 0.5s;
  transition: all 0.5s;
}
.slideUpDown {
  height: 0 !important;
}
.slideLeftRight {
  width: 0 !important;
}
/*  */
/*  */
/* 个性化样式 */
.show-btn {
  width: 100px;
  line-height: 30px;
}
.hide-btn {
  width: 100px;
  line-height: 30px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  display: none;
}
    </style>
  </head>
  <body>
    <!-- show-hide -->
    <button class="show-btn fl">show</button
    ><button class="hide-btn fl">hide</button>
    <div class="box fl"></div>
    <script src="js/jquery-3.4.1.js"></script>

    <script>
// 状态标记,显示状态=1,隐藏状态=0
var state;
var stated;
// 无动画
function init(e, callback) {
    if (e.is(':hidden')) {
        state = 0;
        stated = 0;
    } else { state = 1; stated = 1; };
    if (typeof callback === 'function') callback();
}
function show(e, callback) {
    if (state === 1) return;
    if (stated === 1) return;
    state = 1; e.trigger('show');
    if (typeof callback === 'function') callback();
}
function hide(e, callback) {
    if (state === 0) return;
    if (stated === 0) return;
    state = 0; e.trigger('hide');
    if (typeof callback === 'function') callback();
}
var noanimate = {
    init: init,
    show: function (e) {
        show(e, function () {
            e.show();
            stated = 1; e.trigger('shown');
        })
    },
    hide: function (e) {
        hide(e, function () {
            e.hide();
            stated = 0; e.trigger('hidden');
        })
    }
}
var css3 = {
    fade: {
        init: init,
        show: function (e) {
            show(e, function () {
                e.fadeIn()
                setTimeout(function () {
                    stated = 1; e.trigger('shown');
                }, 2)

            })
        },
        hide: function (e) {
            hide(e, function () {
                e.fadeOut()
                setTimeout(function () {
                    stated = 0; e.trigger('hidden');
                }, 2)

            })
        }
    },
    _init: function (e, classname) {
        e.addClass('transition');
        init(e, function () {
            e.addClass(classname)
        })
    },
    _show: function (e, classname) {
        show(e, function () {
            e.off('transitionend').one('transitionend', function () {
                e.trigger("shown"); stated = 1;
            });
            e.show();
            setTimeout(function () {
                e.removeClass(classname)
            }, 2000);
        })
    },
    _hide: function (e, classname) {
        hide(e, function () {
            e.off('transitionend').one('transitionend', function () {
                e.hide();
                e.trigger("hidden"); stated = 0;
            })
            e.addClass(classname);
        })
    },
    fade_re: {
        init: function (e) {
            css3._init(e, 'fade')
        },
        show: function (e) {
            css3._show(e, 'fade')
        },
        hide: function (e) {
            css3._hide(e, 'fade')
        }
    },
    slideUpDown: {
        init: function (e) {
            // e.height(e.height());
            css3._init(e, 'slideUpDown')
        },
        show: function (e) {
            css3._show(e, 'slideUpDown')
        },
        hide: function (e) {
            css3._hide(e, 'slideUpDown')
        }
    },
    slideLeftRight: {
        init: function (e) {
            // e.height(e.height());
            css3._init(e, 'slideLeftRight')
        },
        show: function (e) {
            css3._show(e, 'slideLeftRight')
        },
        hide: function (e) {
            css3._hide(e, 'slideLeftRight')
        }
    },
    fadeslideUpDown: {
        init: function (e) {
            // e.height(e.height());
            css3._init(e, 'slideUpDown fade')
        },
        show: function (e) {
            css3._show(e, 'slideUpDown fade')
        },
        hide: function (e) {
            css3._hide(e, 'slideUpDown fade')
        }
    },
}

// 执行
      css3.fadeslideUpDown.init($(".box"));
      $(".show-btn").on("click", function() {
        css3.fadeslideUpDown.show($(".box"));
      });
      $(".hide-btn").on("click", function() {
        css3.fadeslideUpDown.hide($(".box"));
      });
      $(".box").on("show shown hide hidden", function(e) {
        console.log(e.type);
      });
    </script>
  </body>
</html>

代码204行,为了解决show函数异步的问题,设置了setTimeout函数,但是自己在实际操作中发现,如果我们给setTimeout一个很大的延迟,比如2000毫秒,那么即使设置了e.off('transitionend'),setTimeout函数无法被中断,也就是说,如果先点击show-btn,然后立即点击hide-btn,是无法触发hide与hidden绑定事件的,请问这是为什么?如何解决这一问题?


正在回答

登陆购买课程后可参与讨论,去登陆

2回答

是因为transitionend是动画结束才会改变stated的值,默认是0 ,当点击show按钮再快速点击hide按钮时,由于定时器设置2s后执行动画,动画没有执行自然transitionend没有办法触发,则stated无法变为1 依旧是0 ,在执行hide函数时,有一个判断是stated为0 就return,所以后面的代码无法触发了啊。要按照你的方式写只能把定时器的时间改小一点,

http://img1.sycdn.imooc.com//climg/5e181a9709c203e205800191.jpg

老铁,我看你的代码和视频中差别太大,你的代码已经没有办法改了。建议你去照着课程中的代码写一下,课程中使用$elem.data('status')定义了好几种状态。例如显示有show也有shown 。当点击显示按钮时,先变成了show,动画变成又设置为shown,点击隐藏按钮时,hide函数中判断,此时shown既不是hide,也不是hidden,所以不会return能够执行。就算是快速点击,动画没有完成,show也不符合if判断,所以也执行hide。

(⊙o⊙)…可能有一点绕,总之照着视频的代码去写一遍吧,

http://img1.sycdn.imooc.com//climg/5e181ece093e8d9405360100.jpg

好帮手慕夭夭 2020-01-10 11:21:13

同学你好,可以继续往下看视频,后面老师会调整代码解决这个问题的。

祝学习愉快!

  • 提问者 慕姐0416137 #1
    我按照视频中方法设置了.off('transitionend'),为什么还是不行?
    2020-01-10 11:36:29
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
2.组件化网页开发
  • 参与学习           人
  • 提交作业       1121    份
  • 解答问题       14456    个

本阶段在运用JS实现动态网页开发的基础上,带你深入理解企业开发核心思想,完成一个企业级网页的开发,体验前端工程师的成就感。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师