【问题标题】:jQuery Mobile 1.3 Panel Not Working After Page ChangejQuery Mobile 1.3 面板在页面更改后不工作
【发布时间】:2013-08-07 22:58:13
【问题描述】:

我似乎在以编程方式打开和关闭 JQM 1.3 面板时遇到问题。

编辑:这是针对 JQM 1.3.x 而不是 1.4+

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

有很多事情发生了,但这只是一个更大的应用程序的示例,并传达了问题。

如何复制:

  1. 去小提琴
  2. 在 Fiddle 打开面板并转到第二页
  3. 在第二页打开面板并转到第一页
  4. 现在尝试在第一页打开面板,它什么也没做。

受影响的浏览器:

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

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

浏览器不受影响:

  • 火狐23
  • Opera 12.16

Fiddle 链接:

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

【问题讨论】:

  • 你应该使用.panel('open').panel('close')而不是隐藏和切换。
  • 如果您使用的是 JQM 1.4alpha1,则面板小部件中存在一个错误,这也可以解释您的问题
  • @Omar 这里是使用打开和关闭的分叉小提琴,但我有相同的结果。 jsfiddle.net/XhupG
  • 将 Safari 添加到受影响的浏览器。
  • Android WebView (4.2.2) 上的同样问题

标签: javascript jquery jquery-mobile


【解决方案1】:

遇到同样的问题,页面更改后面板不显示。

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

我所做的是将面板从 id="myPanel" 更改为 class="myPanel",然后更改对面板的调用以打开:$('.myPanel:visible').panel('open'); - 就是这样!

问题是面板必须在jQuery“页面”内,并且在转换之后,如果您在目标页面中设置了面板,您实际上有两个(或更多)具有相同ID的面板这是错误的或同一类没关系。因此,您只需将 id 更改为一个类并调用可见的类。

花了我太长时间,希望它可以节省其他人的时间。

【讨论】:

  • 请注意,在 jQuery 1.4 中,您不再需要创建页面的子面板。您可以拥有一个位于页面外部并且可以被所有页面访问的主要页面,这非常酷。链接:demos.jquerymobile.com/1.4.0/panel-external
  • 多么美丽的答案。我正在将内容动态加载到仅在页面刷新后才能工作的面板元素。改班对我有用。
【解决方案2】:

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

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

现在警报(); call 有两个效果:(1)它弹出消息框(到目前为止,一切都很好);但是(2)它停止了 JavaScript 正在使用的线程!然而,浏览器的 other 线程仍将继续进行(HTML 渲染...)。因此,您可能会从更优雅的暂停方法中受益,即仅在文档完全加载时执行此(部分)脚本;"

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

【讨论】:

    【解决方案3】:

    好吧,我对@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
    

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2013-01-23
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多