Javascript 如何延迟可折叠文件的扩展,直到获取其内容?

Javascript 如何延迟可折叠文件的扩展,直到获取其内容?,javascript,jquery-mobile,jquery,jquery-mobile-collapsible,Javascript,Jquery Mobile,Jquery,Jquery Mobile Collapsible,我想在我的jQM应用程序(1.3.2)中集成一个可折叠的,如下所示: 它开始折叠 单击后,它开始从服务器获取可折叠文件的listitems。可折叠按钮保持关闭状态,负载图标可能正在旋转 加载所有元素并刷新列表视图并准备就绪后,可折叠文件将展开 如果再次单击它,它将立即直接关闭,并从1开始 我最初的想法是抓住展开事件并阻止其传播。加载完成后,我取消注册我的自定义事件处理程序,将可折叠事件恢复到正常状态,并最终从JavaScript触发expand事件以打开 问题是,这在第一轮中有效,但之后可折叠文

我想在我的jQM应用程序(1.3.2)中集成一个可折叠的,如下所示:

  • 它开始折叠
  • 单击后,它开始从服务器获取可折叠文件的listitems。可折叠按钮保持关闭状态,负载图标可能正在旋转
  • 加载所有元素并刷新列表视图并准备就绪后,可折叠文件将展开
  • 如果再次单击它,它将立即直接关闭,并从1开始
  • 我最初的想法是抓住
    展开
    事件并阻止其传播。加载完成后,我取消注册我的自定义事件处理程序,将可折叠事件恢复到正常状态,并最终从JavaScript触发expand事件以打开

    问题是,这在第一轮中有效,但之后可折叠文件仍然会打开。考虑这个例子(也在里面):

    在这里,如果在加载后单击可折叠文件,它将保持关闭状态(良好)。当您单击“解锁”时,它将打开,并且不会显示任何警报(良好)。如果您再次锁定它,它会显示警报(良好),但无论如何都会打开(不良)

    谁能告诉我我做错了什么?解锁似乎有我看不到的副作用。这里有几个类似的问题,但大多数人都很高兴只是阻止了扩张,而没有再次打开

    因此,我的问题是:什么是延迟可塌陷岩石膨胀的最佳方法?


    编辑:我添加了另一个集成listview逻辑的示例,并显示了此错误。我还移动到
    .one()
    ,以使取消注册更具可追踪性

    新JavaScript:

    var stop = function(event) {
      alert('Locked!');
      event.preventDefault();
    }
    
    // executed after the element is created ...
    $('#c').on('expand', stop)
    
    var stop_n_load = function (event) {
      alert('stop opening! (or at least try to ...)');
    
      // try to stop the expanding by stopping the event
      event.preventDefault();
    
      // Do some work that takes time and trigger expand afterwards ...
      setTimeout(function (e) {
        dd = new Date();
        $('#lv').empty();
        $('#lv').append("<li><a href='#'>Item A ("+dd+")</a></li>");
        $('#lv').append("<li><a href='#'>Item B ("+dd+")</a></li>");
        $('#lv').listview('refresh');
    
        // when done, start expanding without this handler (was register only once)
        $('#c').trigger('expand');
        // for the next collapse register stop_n_load again
        $('#c').one('collapse', reset);
      }, 2000);
    };
    
    var reset = function (event) {
      $('#c').one('expand', stop_n_load);
    };
    
    $('#c').one('expand', stop_n_load);
    
    var stop\u n\u load=函数(事件){
    警报('停止打开!(或至少尝试…);
    //尝试通过停止事件来停止扩展
    event.preventDefault();
    //做一些需要时间的工作,然后触发扩展。。。
    设置超时(函数(e){
    dd=新日期();
    $('#lv').empty();
    $(“#lv”)。追加(“
  • ”); $(“#lv”)。追加(“
  • ”); $('#lv')。listview('refresh'); //完成后,在不使用此处理程序的情况下开始扩展(仅注册一次) $('c')。触发器('expand'); //对于下一个折叠寄存器,请再次停止加载 $('#c')。一个('折叠',重置); }, 2000); }; var重置=功能(事件){ $('c')。一个('expand',stop\n\u load); }; $('c')。一个('expand',stop\n\u load);
    在第一次扩展时,它按预期工作,它首先更新,然后打开。在第二次运行时,它会在不等待的情况下打开,稍后可以看到时间戳更新,因此事件被正确调用


    .preventDefault()似乎有问题。
    我不明白……

    我对JQM不是很熟悉,但我的第一个想法是在发送更多数据之前清空列表……这似乎阻止了它的扩展

    var stop = function(event) {    
        $(this).find('.ui-listview').empty()
        event.preventDefault();
    
        /* do ajax and then refresh component with expand enabled */
    }
    
    $('#c').on('expand', stop);
    

    在事件系统中摸索之后,我现在得出的结论是,如果设置
    preventDefault()
    ,您将永远无法使用它。在charlietfl的解决方案的基础上,我添加了代码以使视觉影响最小化,也许还有一种方法可以防止GUI刷新20毫秒,使其完全不被注意

    var stop_n_load = function (event) {
      $('#lv').empty();
      $('#lv').listview('refresh');
    
      setTimeout(function() {
        $('#c').trigger('collapse');
      }, 20);
    
      // Do some work that takes time and trigger expand afterwards ...
      setTimeout(function () {
        dd = new Date();
        $('#lv').empty();
        $('#lv').append("<li><a href='#'>Item A (" + dd + ")</a></li>");
        $('#lv').append("<li><a href='#'>Item B (" + dd + ")</a></li>");
        $('#lv').listview('refresh');
    
        $('#c').trigger('expand');
        $('#c').one('collapse', reset);
      }, 2000);
    };
    
    var stop\u n\u load=函数(事件){
    $('#lv').empty();
    $('#lv')。listview('refresh');
    setTimeout(函数(){
    $('c')。触发器('collapse');
    }, 20);
    //做一些需要时间的工作,然后触发扩展。。。
    setTimeout(函数(){
    dd=新日期();
    $('#lv').empty();
    $(“#lv”)。追加(“
  • ”); $(“#lv”)。追加(“
  • ”); $('#lv')。listview('refresh'); $('c')。触发器('expand'); $('#c')。一个('折叠',重置); }, 2000); };

    不过,我仍在寻找将事件重置为以前状态的解决方案。

    当触发
    展开
    /
    折叠
    事件时,jQM会添加几个类来显示/隐藏内容以及更新可折叠按钮/标题

    在这种情况下,不会阻止事件冒泡并阻止它们执行。因此,单击标题后,您需要使用停止
    展开
    事件

    折叠可折叠文件时,它有一个类
    ui-collapsable-collapsed
    ,一旦展开,该类将被删除。因此,当触发
    折叠
    时,它工作正常,不会中断

    $(".ui-collapsible-heading-toggle").on("click", function (e) {
    
        // check if collapsible is whether expanded or collapsed
        if ($(this).closest(".ui-collapsible").hasClass("ui-collapsible-collapsed")) {
    
            // true
            // stop "expand" event on click,tap,vclick,touchstart, etc...
            e.stopImmediatePropagation();
    
            // show loading msg - optional
            $.mobile.loading("show", {
                text: "Loading...Please wait",
                textVisible: true
            });
    
            // for demo
            // add items, expand and hide loading msg
            setTimeout(function () {                
                $("#lv").empty().append(items).listview("refresh");
                $("#c").trigger("expand");
                $.mobile.loading("hide");
            }, 1000);
        }
    
        // false
        // collapse normally or do something else
    });
    


    谢谢你的回答,这只是部分解决了我的问题,因为你仍然可以看到可折叠的图标(下面添加了一些空白,图标改变)。整合了你的想法后,你应该会发现问题所在。必须有一个解决方案来解决事件,它在第一次单击时就可以正常工作……我想这取决于浏览器/设备……我的感觉与您在Windows上使用我的开发浏览器FF和Chrome不同。您需要同时使用
    return false
    =
    preventDefault()
    stopPropagation()
    。检查这个谢谢@Omar,这个看起来很棒!为什么单击事件没有第二次单击时仍设置了
    .preventDefault()
    的问题?你能从你的评论中做出一个回答吗?当可折叠展开时,
    ui可折叠折叠
    类被删除,所以第二次点击正常工作。
    $(".ui-collapsible-heading-toggle").on("click", function (e) {
    
        // check if collapsible is whether expanded or collapsed
        if ($(this).closest(".ui-collapsible").hasClass("ui-collapsible-collapsed")) {
    
            // true
            // stop "expand" event on click,tap,vclick,touchstart, etc...
            e.stopImmediatePropagation();
    
            // show loading msg - optional
            $.mobile.loading("show", {
                text: "Loading...Please wait",
                textVisible: true
            });
    
            // for demo
            // add items, expand and hide loading msg
            setTimeout(function () {                
                $("#lv").empty().append(items).listview("refresh");
                $("#c").trigger("expand");
                $.mobile.loading("hide");
            }, 1000);
        }
    
        // false
        // collapse normally or do something else
    });