JQuery Mobile trigger('create') command no

2019-01-15 05:59发布

问题:

JQuery Mobile is making my cry tonight. I'm trying to build custom controls so I don't repeat certain elements through my app, and it's giving me a hard time. Specifically, I have the following in an HTML file:

<div id="custom-header" data-role="header" data-position="inline" data-theme="f">
    <a href="index.html" data-icon="back" style="margin-top:5px" data-theme="b">Back</a>
    <div style="text-align: center; padding-top: 5px; padding-bottom: 3px"><img src="../images/logo.png" ></div>
    <a href="index.html" data-icon="home" style="margin-top:5px" data-theme="b">Home</a>
</div>

In my main file I'm essentially doing:

<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.js"></script>        
<div data-role="page" id="test-console" data-theme="m">

    <div id="me-header"></div>

    <script>

        $.get('header.html', function (retData) {
            $('me-header').html(retData).trigger('create');
        });

     </script>

</div>

So here's the problem - The header doesn't render the same as it does as when I paste the contents of header.html directly into my JQM page. It almost feels like trigger('create') isn't doing anything.

Any ideas? I've burned about three hours and tutorials like http://jquerymobiledictionary.pl/faq.html don't seem to be applying..

回答1:

When changing header, footer or content, you can trigger pagecreate on the page:

$('#me-header').closest(":jqmData(role='page')").trigger('pagecreate');

This is a jQM bug: https://github.com/jquery/jquery-mobile/issues/2703. According to a comment in the issue report, calling pagecreate multiple times may cause problems though, as elaborated in https://github.com/jquery/jquery-mobile/issues/2703#issuecomment-4677293.



回答2:

I believe I've found the 'best' answer available. In short, the 'header' and 'footer' type data-role elements are not standard widgets. They are some sort of hybrid construct. I found this out by just going through the source code of JQueryMobile. They don't have a 'create' method, so it can't be called.

My workaround was to just apply the classes directly to my code, instead of expecting the widget to do it for me. Not ideal, but it works well enough.



回答3:

I've found that the trigger('create');

Works when applied to the body like so:

$('body').append(html).trigger('create');

But the issue I am running into now is the ul list are throwing an undefined error.



回答4:

this question is old enough by now, but I just ran into the problem so here is how I handled it -- (this maintains the set data-theme and applies the correct roles for the containing divs and headers)

$('your_selector').find('div[data-role="header"], div[data-role="footer"]').each(
    function( ){
        var dR = $(this).attr('data-role');
        var dT = $(this).attr('data-theme');
        $(this).addClass('ui-' + dR + ' ui-bar-' + dT).attr('role', (dR == 'header' ? 'banner' : 'contentinfo') ).children('h1, h2, h3, h4').each(
            function( ){
                $(this).addClass('ui-title').attr({'role':'heading', 'aria-level':'1'});
            }
        )
    }
);

depending on your code, it might be more convenient to set this up as a function and send your selector as an argument. Hope it helps.



回答5:

For me, .trigger('create'); always works if applied to the element with data-role="page"

Try This : $('#test-console').trigger('create');

Hope it helps..



回答6:

$('me-header').html(retData).trigger('create');

should be:

$('me-header').append(retData).trigger('create');


回答7:

Perhaps try:

$('#me-header').append(retData).trigger('create');


回答8:

This is not the answer to the specific issue of the OP, but one cause for .trigger('create') not working could be that jQuery Mobile is not loaded properly in the current scope and thus not reacting to the trigger - which can happen in a poorly configured RequireJS-setup for instance.

It doesn't hurt to check console.log($.mobile) in case it shows undefined...



回答9:

As others it make me nuts to inject header in a page. As said by anthony the problem is header is not a "basic" widget. The classes are not added by jqm doing the injection.

I do not like some much to add class ui by my self.

My (crazy?) proposal is to create a brand new page (including the header) and then extract the header tag including all the class ui ceremony added by jqm. I really do not know the perf impact, ... but it seems to work and seems more realiable than adding class by hands.

below is an example. Do you like?

$( '[data-role=page]' ).on( 'pageinit', function ( event, ui ) {
  var sHeader = '<div data-role="header" id="tobechanged" data-position="fixed" data-id="CPL">';
        sHeader += '<a href="#panelImageDetailLeft" data-icon="bars" data-iconpos="notext" data-shadow="false" data-iconshadow="false">Menu1</a>';
        sHeader += '<h1>What a nice title </h1 >';
        sHeader += '<a href="#panelImageDetailRight" data-icon="bars" data-iconpos="notext" data-shadow="false" data-iconshadow="false">Menu2</a>';
sHeader += '</div>';

//Create a temporary page to initialize all the ui-class 
//var sId = core.misc.GUID_new();
var sId = "azerty";
$( '#body' ).append( '<div data-role="page" id="' + sId + '">' + sHeader + '<div data-role="content">content</div></div>' );
$.mobile.initializePage(); //do not know if needed
$( '#' + sId ).page();  //very important to let jqm generate the class ui
//console.log( "page():\n" + $( '#' + sId ).html() );

var $myHeader = $( '#tobechanged' );
//console.log( "tobechanged:\n" + $myHeader.html());

//clean the temporary page
$( '#' + sId ).empty();
$.mobile.initializePage(); //do not know if needed

//replace the id
//console.log( "myheader id: ... " + $myHeader.attr( "id" ) ); 
$myHeader.attr( "id", $( "#" + event.target.id ).attr("id") + "Header" );
//console.log( "myheader id: ... " + $myHeader.attr( "id" ) ); 

$( "#" + event.target.id ).find( "[data-role=header]" ).replaceWith( $myHeader );

});



回答10:

Calling:

trigger('pagecreate');

immediately after:

trigger('create');

works for me.