最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery Mobile 1.3 Panel Not Working After Page Change - Stack Overflow

programmeradmin1浏览0评论

I seem to be having issues with programmatic opening and closing of a JQM 1.3 Panel.

EDIT: This is for JQM 1.3.x not 1.4+

It is somewhat hard to explain, so I just made a fiddle :)

There is a lot going on in the fiddle, but it is just a sample of a much larger app and conveys the issue.

How to replicate:

  1. Go to Fiddle
  2. On Fiddle open the Panel and go to Page Two
  3. On Page Two open Panel and go to Page One
  4. Try to Open the Panel now on page one, it does nothing.

Browsers Affected:

EDIT: This seems to be fixed in Chrome 30.0.1599.101 m

  • Chrome 28.0.1500.95 m
  • IE 10.0.9200.16635
  • Safari // Latest Ver
  • Android WebView (4.2.2)

Browsers NOT Affected:

  • Firefox 23
  • Opera 12.16

Link to Fiddle:

/

Link to Other Posts

EDIT: So Firefox gives me an error that neither Chrome or IE do.

When I click to go back to page one, I get:

Type Error: elem is undefined

The error is thrown by JQ 1.9.1, I trace it back to this:

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;
    }
`

Note the :

Do not set data on non-element because it will not be cleared (#8335).

Github Issue Link:

OG Code:

$('.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

I seem to be having issues with programmatic opening and closing of a JQM 1.3 Panel.

EDIT: This is for JQM 1.3.x not 1.4+

It is somewhat hard to explain, so I just made a fiddle :)

There is a lot going on in the fiddle, but it is just a sample of a much larger app and conveys the issue.

How to replicate:

  1. Go to Fiddle
  2. On Fiddle open the Panel and go to Page Two
  3. On Page Two open Panel and go to Page One
  4. Try to Open the Panel now on page one, it does nothing.

Browsers Affected:

EDIT: This seems to be fixed in Chrome 30.0.1599.101 m

  • Chrome 28.0.1500.95 m
  • IE 10.0.9200.16635
  • Safari // Latest Ver
  • Android WebView (4.2.2)

Browsers NOT Affected:

  • Firefox 23
  • Opera 12.16

Link to Fiddle:

http://jsfiddle.net/q2YH3/

Link to Other Posts

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

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

EDIT: So Firefox gives me an error that neither Chrome or IE do.

When I click to go back to page one, I get:

Type Error: elem is undefined

The error is thrown by JQ 1.9.1, I trace it back to this:

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;
    }
`

Note the :

Do not set data on non-element because it will not be cleared (#8335).

Github Issue Link: https://github.com/jquery/jquery/pull/1232

OG Code:

$('.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
Share Improve this question edited Feb 9, 2014 at 0:20 Red2678 asked Aug 6, 2013 at 19:14 Red2678Red2678 3,2972 gold badges32 silver badges45 bronze badges 8
  • You should use .panel('open') and .panel('close') not hide and toggle. – Omar Commented Aug 6, 2013 at 19:44
  • If you are using JQM 1.4alpha1, there is a bug in the panel widget, which could also explain your issue – frequent Commented Aug 6, 2013 at 19:50
  • 1 @Omar here is a forked fiddle using Open and Close, but I have the same result. jsfiddle.net/XhupG – Red2678 Commented Aug 6, 2013 at 19:54
  • 2 Add Safari to the browsers affected. – Omar Commented Aug 6, 2013 at 21:04
  • 1 same problem on Android WebView (4.2.2) – Paranoid Android Commented Oct 30, 2013 at 11:42
 |  Show 3 more comments

3 Answers 3

Reset to default 13

Had the same problem, panel not showing after page changes.

Two small changes can fix that:

what I did was to change the panel from id="myPanel" to class="myPanel", then changed the call to the panel to open: $('.myPanel:visible').panel('open'); - that's it!

The problem is that the panel has to be inside of a jQuery "page", and after the transition, if you have the panel set in the target page, you actually have two (or more) panels with the same id which is wrong or same class which is fine. So you just change the id to a class and call the visible one.

Took me too long, Hope it saves time to someone else.

I played around with your code a bit. I noticed that If I put an alert inside your update function, that it fixes everything. So I researched why an alert would make a program work, and found this page. http://ubuntuforums.org/archive/index.php/t-930002.html

"You should probably know that JavaScript evaluation is of the 'look ahead' type: the script already runs when it is still being evaluated (and while the page itself is still being evaluated). Now that is why it is recommended to dump all references to scripts in the section of your page, as it will cause the JavaScript to be fully evaluated before you (usually) can call a function (event handlers), and hence avoid silly 'undefined' errors.

Now the alert(); call has 2 effects: (1) it pops up the message box (so far, so good);.but (2) it halts the thread the JavaScript is using! However the browser's other threads will still continue to go on (HTML rendering...). So it may be one of those cases that you would benefit from a more elegant halting method, which is to only execute this (part of the) script when the document has been fully loaded;"

The solution they suggest is putting your script inside of the . Or using "stateChanged() function of the ajax http request".

Well I upvoted @A.sharif 's post, as he got the gears in my head spinning.

The problem lies in the fact that the callback of the "BuildUrl" function was executing before the URL variable was built.

I thought I had allowed ample time with 25ms but it was not. I bumped the time before the callback is executed up to 600 ms and it works fine now.

I am sure there is a more elegant solution, but this is what I got ;)

New Fiddle:

http://jsfiddle.net/t8zyQ/

What was changed was the value of 25 in the setTimeout() to 600.

Changed Code:

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
发布评论

评论列表(0)

  1. 暂无评论