【问题标题】:Proper way to slideToggle then dynamically create content and slideToggle back滑动切换的正确方法,然后动态创建内容和滑动切换
【发布时间】:2020-10-16 10:59:19
【问题描述】:

我有一个包含一些元素的 div。当用户选择一个按钮时,div 被清除并动态填充新内容。我在清除 div 之前和填充它之后运行 slideToggle。隐藏 div 的第一个切换工作正常。第二个 slideToggle 没有运行(新的 div 只是在没有动画的情况下加载)。

我花了几个小时尝试不同的事情(回调函数、.on、promise、将第二个 slideToggle 函数放在代码的不同部分等)。我终于通过使用时间为 1 毫秒的 setTimeout 让它工作了。尽管它起作用了,但我比以往任何时候都更加困惑,并且质疑我生活中的一切。请帮助我了解发生了什么。

工作代码:

changeCat:function(catName){
    domObject.$positionsDiv.slideToggle(function(){
        domObject.$positionsDiv.html('');
        let yourCategories = getSubFolders(catName+"/");

        if(catName==='s'){
            tSCat.drawCats(yourCategories);

        } else if(catName==='g'){
            tGCat.drawCats(yourCategories);
        }
        setTimeout(function (){
            domObject.$positionsDiv.slideToggle(function(){
                resizeCanvas()
            });
        }, 1)

    });
},

真正让我困惑的是,如果我控制台记录目标 div 的高度。

  • 我希望最后调用的控制台日志(“高度 5”)被首先调用。
  • div 高度(“height 3”)是在我调用第二个切换之前完全填充的 div 的高度(为什么它不起作用?)。

非工作代码(无超时,带有控制台日志)

changeCat:function(catName){
    domObject.$positionsDiv.slideToggle(function(){
        console.log('height 1: ' + domObject.$positionsDiv.height())
        domObject.$positionsDiv.html('');
        console.log('height 2: ' + domObject.$positionsDiv.height())
        let yourCategories = getSubFolders(catName+"/");

        if(catName==='s'){
            tSCat.drawCats(yourCategories);

        } else if(catName==='g'){
            tGCat.drawCats(yourCategories);
        }

        console.log('height 3: ' + domObject.$positionsDiv.height())
            domObject.$positionsDiv.slideToggle(function(){
                console.log('height 4: ' + domObject.$positionsDiv.height())
                resizeCanvas()
            });
    });
    console.log('height 5: ' + domObject.$positionsDiv.height())
},

按此顺序返回的控制台日志具有以下值:

height 5: 359.333 
height 1: 2214 
height 2: 0
height 3: 3744
height 4: 324

【问题讨论】:

    标签: javascript jquery dom slidetoggle


    【解决方案1】:

    “传统”方式是将“显示”代码放在“隐藏”回调中:

    $("#d").slideToggle(function() {
      $(this).html("a<br/>b<br/>c<br/>");
      $(this).slideToggle()
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id='d'>
      1<br/>2<br/>3<br/>
    </div>

    在 1 毫秒超时后调用“show”与立即调用“show”是一样的。

    .slideToggle() 使用 .animate() 并且同一 DOM 节点上的每个 .animate() 调用都会排队。那么会发生什么:

    • 你的“隐藏”开始
    • “表演”已排队
    • 隐藏完成,调用回调设置内容,而“不可见”
    • 显示自动出队

    $("#d").slideToggle(function() {
      $(this).html("a<br/>b<br/>c<br/>");
    });
    $(this).slideToggle()
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id='d'>
      1<br/>2<br/>3<br/>
    </div>

    【讨论】:

    • "在 1 毫秒超时后调用 "show" 与立即调用 "show" 时发生的情况相同。" ... 谢谢回复。也许我错过了它,但我发布的“非工作代码”不正是这样做的吗?
    • 抱歉,在您的情况下它们并不相同,因为它们都是从回调内部调用的,而我的示例是在回调外部调用的。在您的情况下,如果它与最小的 setTimeout 一起工作,那么原因将是在两者之间运行异步/可能是事件处理程序的其他东西,因此您需要等待它“完成” - setTimeout 所做的。所以很可能是tGCat.drawCats
    • 啊,你认为这可能与此有关。谢谢你。你认为这就是console.log首先输出“height 5”的原因吗?
    • 是的,高度 5 是第一个运行的 console.log,因为 javascript 是单线程的,所以在您的代码完成之前动画不会/无法启动。
    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多