jQuery Mobile: Markup-Verbesserung von dynamisch hinzugefügten Inhalten

75

Ich habe mich gefragt, wie ich die jQuery Mobile-Seite dynamisch verbessern kann.

Ich habe versucht, diese Methoden zu verwenden:

  1. $('[data-role="page"]').trigger('create');

    und

  2. $('[data-role="page"]').page();

Wie kann ich auch verhindern, dass nur Kontrollkästchen erweitert werden?

user2001897
quelle
Was ist passiert, als Sie .trigger ('create') für ein Element ausgeführt haben, das die Elemente enthält, die Sie verbessern möchten?
Josh

Antworten:

165

Haftungsausschluss:

Dieser Artikel ist auch als Teil meines Blogs HIER zu finden .

Intro:

Es gibt verschiedene Möglichkeiten, dynamisch erstellte Inhaltsmarkierungen zu verbessern. Es reicht einfach nicht aus, der jQuery Mobile- Seite dynamisch neuen Inhalt hinzuzufügen. Neuer Inhalt muss mit dem klassischen jQuery Mobile- Stil erweitert werden. Da dies eher eine schwere Aufgabe ist, müssen einige Prioritäten gesetzt werden. Wenn möglich, muss jQuery Mobile so wenig wie möglich verbessert werden. Verbessern Sie nicht die gesamte Seite, wenn nur eine Komponente gestaltet werden muss.

Was bedeutet das alles? Wenn das Seiten-Plugin ein pageInit- Ereignis auslöst , das die meisten Widgets verwenden, um sich automatisch zu initialisieren. Alle Instanzen der Widgets, die auf der Seite gefunden werden, werden automatisch erweitert.

Wenn Sie jedoch clientseitig neues Markup generieren oder Inhalte über Ajax laden und in eine Seite einfügen, können Sie das Erstellungsereignis auslösen, um die automatische Initialisierung für alle im neuen Markup enthaltenen Plugins durchzuführen. Dies kann für jedes Element (sogar für das Seitenteil) ausgelöst werden, sodass Sie nicht jedes Plugin manuell initialisieren müssen (Listenansichtstaste, Auswahl usw.).

In diesem Sinne können wir die Verbesserungsstufen diskutieren. Es gibt drei von ihnen, und sie sind von weniger ressourcenintensiv bis höher sortiert:

  1. Erweitern Sie eine einzelne Komponente / ein Widget
  2. Erweitern Sie den Seiteninhalt
  3. Verbessern Sie den Inhalt einer ganzen Seite (Kopf-, Inhalts- und Fußzeile).

Erweitern Sie eine einzelne Komponente / ein Widget:

Wichtig: Die folgenden Erweiterungsmethoden dürfen nur auf der aktuellen / aktiven Seite verwendet werden. Bei dynamisch eingefügten Seiten werden diese Seiten und ihr Inhalt nach dem Einfügen in DOM erweitert. Das Aufrufen einer beliebigen Methode für dynamisch erstellte / andere Seiten als die aktive Seite führt zu einem Fehler.

Jedes jQuery Mobile- Widget kann dynamisch erweitert werden:

  1. Listenansicht :

    Markup-Verbesserung:

    $('#mylist').listview('refresh');
    

    Listenansichtselemente entfernen:

    $('#mylist li').eq(0).addClass('ui-screen-hidden'); 
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/LrAyE/

    Beachten Sie, dass die Methode refresh () nur neue Knoten betrifft, die an eine Liste angehängt sind. Dies erfolgt aus Leistungsgründen.

    Einer der Höhepunkte einer Listenansicht ist eine Filterfunktion. Leider kann jQuery Mobile aus irgendeinem Grund keine Filteroption dynamisch zu einer vorhandenen Listenansicht hinzufügen. Zum Glück gibt es eine Problemumgehung. Entfernen Sie nach Möglichkeit die aktuelle Listenansicht und fügen Sie eine weitere mit aktivierter Filer-Option hinzu.

    Hier ist ein funktionierendes Beispiel: https://stackoverflow.com/a/15163984/1848600

    $(document).on('pagebeforeshow', '#index', function(){       
        $('<ul>').attr({'id':'test-listview','data-role':'listview', 'data-filter':'true','data-filter-placeholder':'Search...'}).appendTo('#index [data-role="content"]');
        $('<li>').append('<a href="#">Audi</a>').appendTo('#test-listview');
        $('<li>').append('<a href="#">Mercedes</a>').appendTo('#test-listview');
        $('<li>').append('<a href="#">Opel</a>').appendTo('#test-listview');
        $('#test-listview').listview().listview('refresh');
    });
    
  2. Taste

    Markup-Verbesserung:

    $('[type="button"]').button();
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/m4rjZ/

    Eine weitere Sache, Sie müssen kein Eingabeelement verwenden, um eine Schaltfläche zu erstellen. Dies kann sogar mit einem einfachen div erfolgen. Hier ein Beispiel: http://jsfiddle.net/Gajotres/L9xcN/

  3. Navbar

    Markup-Verbesserung:

    $('[data-role="navbar"]').navbar();
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/w4m2B/

    Hier ist eine Demo zum Hinzufügen einer dynamischen Registerkarte "Navigationsleiste": http://jsfiddle.net/Gajotres/V6nHp/

    Und noch eine in pagebeforecreate event: http://jsfiddle.net/Gajotres/SJG8W/

  4. Texteingaben, Sucheingaben und Textbereiche

    Markup-Verbesserung:

    $('[type="text"]').textinput();   
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/9UQ9k/

  5. Schieberegler & Kippschalter

    Markup-Verbesserung:

    $('[type="range"]').slider();  
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/caCsf/

    Verbesserungsbeispiel während des Ereignisses pagebeforecreate: http://jsfiddle.net/Gajotres/NwMLP/

    Schieberegler sind etwas fehlerhaft zu erstellen. Weitere Informationen finden Sie hier: https://stackoverflow.com/a/15708562/1848600

  6. Kontrollkästchen & Radiobox

    Markup-Verbesserung:

    $('[type="radio"]').checkboxradio();
    

    oder wenn Sie ein anderes Radiobox / Checkbox-Element aktivieren / deaktivieren möchten:

    $("input[type='radio']").eq(0).attr("checked",false).checkboxradio("refresh");
    

    oder

    $("input[type='radio']").eq(0).attr("checked",true).checkboxradio("refresh");
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/VAG6F/

  7. Menü auswählen

    Markup-Verbesserung:

    $('select').selectmenu();  
    

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/dEXac/

  8. Zusammenklappbar

    Leider kann das zusammenklappbare Element nicht durch eine bestimmte Methode erweitert werden, daher muss stattdessen der Trigger ('create') verwendet werden.

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/ck6uK/

  9. Tabelle

    Markup-Verbesserung:

    $(".selector").table("refresh");
    

    Dies ist zwar eine Standardmethode zur Tabellenerweiterung, aber ich kann sie derzeit nicht zum Laufen bringen. Verwenden Sie stattdessen Trigger ('create').

    Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/Zqy4n/

  10. Panels - Neu

    Panel Markup-Verbesserung:

    $('.selector').trigger('pagecreate');
    

    Markup-Verbesserung von Inhalten, die dynamisch zum Panel hinzugefügt wurden :

    $('.selector').trigger('pagecreate');
    

    Beispiel: http://jsfiddle.net/Palestinian/PRC8W/

Seiteninhalt verbessern:

Wenn wir den gesamten Seiteninhalt generieren / neu erstellen, ist es am besten, alles auf einmal zu tun, und dies kann folgendermaßen geschehen:

$('#index').trigger('create');

Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/426NU/

Erweitern Sie den Inhalt einer ganzen Seite (Kopf-, Inhalts- und Fußzeile):

Leider kann Trigger ('create') das Kopf- und Fußzeilen-Markup nicht verbessern. In diesem Fall brauchen wir große Waffen:

$('#index').trigger('pagecreate');

Verbesserungsbeispiel: http://jsfiddle.net/Gajotres/DGZcr/

Dies ist fast eine mystische Methode, da ich sie in der offiziellen jQuery Mobile- Dokumentation nicht finden kann . Trotzdem ist es im jQuery Mobile Bug Tracker leicht zu finden, mit der Warnung, es nicht zu verwenden, es sei denn, es ist wirklich wirklich notwendig.

Beachten Sie, .trigger ('pagecreate'); Ich kann davon ausgehen, dass es nur einmal pro Seitenaktualisierung verwendet wird. Ich fand es falsch:

http://jsfiddle.net/Gajotres/5rzxJ/

Erweiterungs-Plugins von Drittanbietern

Es gibt mehrere Erweiterungs-Plugins von Drittanbietern. Einige werden als Aktualisierung einer vorhandenen Methode vorgenommen, andere dienen zur Behebung fehlerhafter jQM-Funktionen.

  • Änderung des Schaltflächentextes

    Leider kann der Entwickler dieses Plugins nicht gefunden werden. Ursprüngliche SO-Quelle: Ändern Sie den Schaltflächentext jquery mobile

    (function($) {
        /*
         * Changes the displayed text for a jquery mobile button.
         * Encapsulates the idiosyncracies of how jquery re-arranges the DOM
         * to display a button for either an <a> link or <input type="button">
         */
        $.fn.changeButtonText = function(newText) {
            return this.each(function() {
                $this = $(this);
                if( $this.is('a') ) {
                    $('span.ui-btn-text',$this).text(newText);
                    return;
                }
                if( $this.is('input') ) {
                    $this.val(newText);
                    // go up the tree
                    var ctx = $this.closest('.ui-btn');
                    $('span.ui-btn-text',ctx).text(newText);
                    return;
                }
            });
        };
    })(jQuery);
    

    Arbeitsbeispiel: http://jsfiddle.net/Gajotres/mwB22/

Erhalten Sie die richtige maximale Inhaltshöhe

Falls Kopf- und Fußzeile der Seite eine konstante Höhe haben, kann der Inhaltsbereich einfach so eingestellt werden, dass er mit einem kleinen CSS-Trick den gesamten verfügbaren Speicherplatz abdeckt:

#content {
    padding: 0;
    position : absolute !important; 
    top : 40px !important;  
    right : 0; 
    bottom : 40px !important;  
    left : 0 !important;     
}

Und hier ist ein funktionierendes Beispiel mit Google maps api3Demo: http://jsfiddle.net/Gajotres/7kGdE/

Diese Methode kann verwendet werden, um die korrekte maximale Inhaltshöhe zu erhalten, und muss mit einem Pageshow- Ereignis verwendet werden.

function getRealContentHeight() {
    var header = $.mobile.activePage.find("div[data-role='header']:visible");
    var footer = $.mobile.activePage.find("div[data-role='footer']:visible");
    var content = $.mobile.activePage.find("div[data-role='content']:visible:visible");
    var viewport_height = $(window).height();

    var content_height = viewport_height - header.outerHeight() - footer.outerHeight();
    if((content.outerHeight() - header.outerHeight() - footer.outerHeight()) <= viewport_height) {
        content_height -= (content.outerHeight() - content.height());
    } 
    return content_height;
}

Und hier ist ein Live-Beispiel für jsFiddle: http://jsfiddle.net/Gajotres/nVs9J/

Es gibt eine Sache, an die man sich erinnern muss. Mit dieser Funktion erhalten Sie die maximal verfügbare Inhaltshöhe korrekt und können gleichzeitig zum Strecken desselben Inhalts verwendet werden. Leider kann es nicht verwendet werden, um img auf die volle Höhe des Inhalts zu strecken. Das img-Tag hat einen Overhead von 3px.

Methoden zur Verhinderung von Markup-Verbesserungen:

Dies kann auf verschiedene Arten erfolgen. Manchmal müssen Sie sie kombinieren, um das gewünschte Ergebnis zu erzielen.

  • Methode 1:

    Dies kann durch Hinzufügen dieses Attributs erreicht werden:

    data-enhance="false"
    

    zum Header, Inhalt, Fußzeilencontainer.

    Dies muss auch in der Ladephase der App aktiviert werden:

    $(document).one("mobileinit", function () {
        $.mobile.ignoreContentEnabled=true;
    });
    

    Initialisieren Sie es, bevor jquery-mobile.js initialisiert wird (siehe Beispiel unten).

    Mehr dazu finden Sie hier:

    http://jquerymobile.com/test/docs/pages/page-scripting.html

    Beispiel: http://jsfiddle.net/Gajotres/UZwpj/

    Verwenden Sie Folgendes, um eine Seite erneut zu erstellen:

    $('#index').live('pagebeforeshow', function (event) {
        $.mobile.ignoreContentEnabled = false;
        $(this).attr('data-enhance','true');
        $(this).trigger("pagecreate")
    });
    
  • Methode 2:

    Die zweite Möglichkeit besteht darin, dies manuell mit dieser Zeile zu tun:

    data-role="none"
    

    Beispiel: http://jsfiddle.net/Gajotres/LqDke/

  • Methode 3:

    Bestimmte HTML-Elemente können an der Markup-Verbesserung gehindert werden:

     $(document).bind('mobileinit',function(){
          $.mobile.page.prototype.options.keepNative = "select, input";
     });    
    

    Beispiel: http://jsfiddle.net/Gajotres/gAGtS/

    Initialisieren Sie es erneut, bevor jquery-mobile.js initialisiert wird (siehe Beispiel unten).

Probleme bei der Markup-Verbesserung:

Manchmal tritt beim Erstellen einer Komponente von Grund auf neu (z. B. Listenansicht) der folgende Fehler auf:

Vor der Initialisierung können keine Methoden in der Listenansicht aufgerufen werden

Mit der Komponenteninitialisierung vor der Markup-Verbesserung kann dies verhindert werden. So können Sie Folgendes beheben:

$('#mylist').listview().listview('refresh');

Probleme beim Überschreiben von Markups:

Wenn aus irgendeinem Grund das Standard-jQuery Mobile-CSS geändert werden muss, muss dies mit !importantÜberschreibung erfolgen. Ohne sie können Standard-CSS-Stile nicht geändert werden.

Beispiel:

#navbar li {
    background: red !important;
}

jsFiddleBeispiel: http://jsfiddle.net/Gajotres/vTBGa/

Änderungen:

  • 01.02.2013 - Eine dynamische Navbar-Demo wurde hinzugefügt
  • 01.03.2013 - Kommentar zum dynamischen Hinzufügen von Filtern zu einer Listenansicht hinzugefügt
  • 07.03.2013 - Neues Kapitel hinzugefügt: Richtige maximale Inhaltshöhe ermitteln
  • 17.03.2013 - Einige Wörter zum Kapitel hinzugefügt: Richtige maximale Inhaltshöhe ermitteln
  • 29.03.2013 - Neue Inhalte zu dynamisch erstellten Schiebereglern hinzugefügt und ein Beispielfehler behoben
  • 03.04.2013 - Neuer Inhalt zu dynamisch erstellten reduzierbaren Elementen hinzugefügt
  • 04.04.2013 - Kapitel Plugins von Drittanbietern hinzugefügt
  • 20.05.2013 - Dynamisch hinzugefügte Panels und Inhalte hinzugefügt
  • 21.05.2013 - Eine weitere Möglichkeit zum Festlegen der vollen Inhaltshöhe wurde hinzugefügt
  • 20.06.2013 - Neues Kapitel hinzugefügt: Probleme beim Überschreiben von Markups
  • 29.06.2013 - Es wurde ein wichtiger Hinweis zu WANN hinzugefügt, um Verbesserungsmethoden zu verwenden
Gajotres
quelle
1
@ Gajotres ausgezeichnete Erklärung
Nikhil Agrawal
2
Ich wünschte, ich könnte +6 hinzufügen, dies ist die beste Antwort, die ich seit langer Zeit gesehen habe. Vielen Dank dafür, jetzt nur, wenn die Dokumentation für jQuery Mobile so einfach war. VIELEN DANK! Eine Frage ist jedoch, dass ich einen Header habe, den ich ändere. Gibt es eine ähnliche Methode für einen Header? $ (": jqmData (role = 'header')"). header ()?
Chris
Wenn Sie den Header erweitern möchten, müssen Sie den Trigger ('pagecreate') verwenden. Sie finden ihn in meiner Antwort.
Gajotres
Ich möchte ein Eingabefeld mit type = "password" erweitern, wenn ich $ ("# acntNewPW") versuche. Textinput (); Ich bekomme den klassischen Stil und dahinter den neuen jquery Mobile Style.
Alexander-Feuer
Dies tritt normalerweise auf, wenn jQuery Mobile js mit jQuery Mobile css nicht übereinstimmt. Gehen Sie zu ihrer offiziellen Seite und laden Sie die neuesten Versionen herunter und versuchen Sie es erneut.
Gajotres
4

Von JQMobile 1.4 können Sie tun .enhanceWithin () auf alle Kinder http://api.jquerymobile.com/enhanceWithin/

var content = '<p>Hi</p>';
$('#somediv').html(content);
$('#somediv').enhanceWithin();
zzart
quelle
Ist dies vorzuziehen $('#somediv').trigger('create')und wenn ja, warum?
Josh
.trigger ("create") ist veraltet. Sie können stattdessen die neue Methode .enhanceWithin () verwenden. Wenn Sie beispielsweise dynamisch eine reduzierbare Datei mit einer ul mit data-role = "listview" hinzufügen, können Sie das Listenview-Plugin mit .enhanceWithin () initialisieren.
Zzart
Ist es ein Problem, diese Methode für ein Element aufzurufen, dessen untergeordnete Elemente bereits erweitert wurden?
Josh
Ich bin mir eines solchen Problems nicht bewusst. Diese Methode geht jedoch durch alle untergeordneten Elemente des Selektors und versucht, alles zu verbessern, was er finden kann. In einigen Fällen ist es nicht das Schnellste, große Teile von DOM zu
durchqueren