页面更改后jQuery Mobile 1.3面板无法正常工作

时间:2013-08-06 19:14:05

标签: javascript jquery jquery-mobile

我似乎遇到了程序化打开和关闭JQM 1.3面板的问题。

编辑:这适用于JQM 1.3.x而不是1.4 +

这有点难以解释,所以我只是做了一个小提琴:)

小提琴中有很多内容,但它只是一个更大的应用程序的样本,并传达了这个问题。

如何复制:

  1. 转到小提琴
  2. On Fiddle打开面板并转到第二页
  3. 在第二页上打开Panel并转到第一页
  4. 尝试在第一页上打开面板,它什么都不做。
  5. 受影响的浏览器:

    编辑:这似乎在Chrome 30.0.1599.101 m中得到修复

    • Chrome 28.0.1500.95 m
    • IE 10.0.9200.16635
    • Safari //最新版本
    • Android WebView(4.2.2)

    不受影响的浏览器:

    • Firefox 23
    • Opera 12.16

    链接到小提琴:

    http://jsfiddle.net/q2YH3/

    链接到其他帖子

    https://github.com/jquery/jquery-mobile/issues/6308

    http://forum.jquery.com/topic/panel-not-responding-after-page-change

    编辑:因此Firefox给我一个Chrome或IE都没有的错误。

    当我点击返回第一页时,我得到:

    Type Error: elem is undefined

    JQ 1.9.1引发了错误,我将其追溯到:

    A method for determining if a DOM node can handle the data expando
        acceptData: function( elem ) {
            // Do not set data on non-element because it will not be cleared (#8335).
            if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
                return false;
            }
    
            var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
    
            // nodes accept data unless otherwise specified; rejection can be conditional
            return !noData || noData !== true && elem.getAttribute("classid") === noData;
        }
    `
    

    请注意:

    不要在非元素上设置数据,因为它不会被清除(#8335)。

    Github问题链接: https://github.com/jquery/jquery/pull/1232

    OG代码:

    $('.showMenu').on('click', function(){
    $.mobile.loading('hide');
    $.mobile.activePage.find('#'+$.mobile.activePage.attr('id')+'P').panel("toggle");
    });
    
    $('.btnMenuItem').on('click', function(event){
    myPgActions.nav(event, function(target){
        $.mobile.changePage(target);
    }, false);
    });   
    
    var myPgActions = {};
    
    myPgActions = {
    nav: function(event, callback, manualHash){
        var PID = $.mobile.activePage.attr('id'),
        target = (!!event) ? event.target.name : manualHash;    
        $("#"+PID+"P").panel( "close" );
        if(PID != 'loading') $("#"+PID+"Iframe").hide();        
    
        if(PID == target){
            $("#"+PID+"Iframe").hide('fast', function(){
                $("#"+PID+"Iframe").attr('src', "");
    
                myPgActions.update(PID, target, 'refresh', function(target){
                    callback(target)
                });
            }); 
    
        }else{
    
            this.update(PID, target, 'change', function(target){
                callback(target);
            });
    
        }
    
    },// end get
    
    update: function(PID, target, type, updateCallback){
    
        var ifReady = $.Deferred();
    
        if(type == 'refresh'){
    
            this.buildUrl(PID, function(url){
    
                $('#'+PID+'Iframe').attr( 'src', url);
                ifReady.resolve();          
    
                $.when(ifReady).then(function(){
                    updateCallback('#'+PID+'Iframe')        
                });
            });
    
        }else if(type == 'change'){
    
            this.buildUrl(target, function(url){
                $('#'+target+'Iframe').attr( 'src', url);
                ifReady.resolve();
            });
    
            $.when(ifReady).then(function(){
                updateCallback('#'+target); 
            });
        }
    }, // end set
    buildUrl: function(page, buildCallback){
        switch(page){
            case 'dash':        
                var mobileSiteUrl = 'URL with options for iframe'
                setTimeout(function(){buildCallback(mobileSiteUrl);},25);
            break;
            case 'local':
                var mobileSiteUrl = 'URL with options for iframe'
                setTimeout(function(){buildCallback(mobileSiteUrl);},25);   
            break;
    
    
        }// End Switch
    }
    }// End Obj
    

3 个答案:

答案 0 :(得分:13)

出现同样的问题,面板在页面更改后没有显示。

两项小改动可以解决这个问题:

我所做的是从 id =" myPanel"更改面板到 class = " myPanel",然后将调用更改为面板打开: $(' .myPanel:visible')。panel(& #39;打开'); - 那就是它!

问题是面板必须位于jQuery"页面"内,并且在转换后,如果您在目标页面中设置了面板,则实际上有两个(或更多)面板同一个ID 哪个错误或同一个类哪个很好。所以你只需将id更改为类并调用可见的。

我花了太长时间,希望能节省时间给别人。

答案 1 :(得分:1)

我玩了一下你的代码。我注意到如果我在你的更新功能中放了一个警报,那就修复了一切。所以我研究了为什么警报会使程序工作,并找到了这个页面。 http://ubuntuforums.org/archive/index.php/t-930002.html

“您可能应该知道JavaScript评估属于'向前看'类型:脚本在仍在评估时已经运行(并且页面本身仍在评估中)。现在这就是为什么建议在页面部分转储脚本的所有引用,因为它会导致JavaScript(通常)在调用函数(事件处理程序)之前进行全面评估,从而避免愚蠢的“未定义”错误。

现在提醒(); call有2个效果:(1)它会弹出消息框(到目前为止,这么好);但是(2)它会停止JavaScript正在使用的线程!但是,浏览器的其他线程仍将继续(HTML呈现...)。因此,您可以从更优雅的暂停方法中受益,其中一种情况是,只有在文档完全加载时才执行此(部分)脚本;“

他们建议的解决方案是将你的脚本放在。或者使用ajax http请求的“stateChanged()函数”。

答案 2 :(得分:0)

好吧,我赞成@ A.sharif的帖子,因为他让我的脑袋旋转着。

问题在于“BuildUrl”函数的回调是在构建URL变量之前执行的。

我以为我已经允许25毫秒充足的时间,但事实并非如此。我在回调执行到600毫秒之前碰到了时间,现在工作正常。

我确信有一个更优雅的解决方案,但这就是我得到的;)

新小提琴:

http://jsfiddle.net/t8zyQ/

更改的内容是setTimeout()中 25 的值为 600

更改代码:

buildUrl: function(page, buildCallback){
    switch(page){
        case 'dash':        
            var mobileSiteUrl = 'URL with options for iframe'
            setTimeout(function(){buildCallback(mobileSiteUrl);},600);
        break;
        case 'local':
            var mobileSiteUrl = 'URL with options for iframe'
            setTimeout(function(){buildCallback(mobileSiteUrl);},600);  
        break;


    }// End Switch