jQuery Mobile: улучшение разметки динамически добавляемого контента

Мне было интересно, как я могу динамически улучшить страницу jQuery Mobile?

Я пытался использовать эти методы:

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

    а также

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

Кроме того, как я могу предотвратить расширение разметки только для флажков?

2 ответа

Решение

Отказ от ответственности:

Эту статью также можно найти как часть моего блога ЗДЕСЬ.

Вступление:

Есть несколько способов улучшить динамически создаваемую разметку контента. Недостаточно динамически добавлять новый контент на страницу jQuery Mobile, новый контент должен быть дополнен классическим стилем jQuery Mobile. Поскольку это довольно трудоемкая задача, должны быть некоторые приоритеты, если возможно, jQuery Mobile должен делать как можно меньше улучшений. Не улучшайте всю страницу, если требуется стилизовать только один компонент.

Что это все значит? Когда плагин страницы отправляет событие pageInit, которое большинство виджетов используют для автоматической инициализации. это автоматически улучшит все экземпляры виджетов, которые он найдет на странице.

Однако, если вы генерируете новую разметку на стороне клиента или загружаете контент через Ajax и внедряете его в страницу, вы можете инициировать событие create для обработки автоинициализации всех плагинов, содержащихся в новой разметке. Это может быть запущено на любом элементе (даже на самой странице div), избавляя вас от необходимости вручную инициализировать каждый плагин (кнопка просмотра списка, выбор и т. Д.).

Имея это в виду, давайте обсудим уровни улучшения. Их три, и они отсортированы от менее требовательных к более высоким:

  1. Улучшение одного компонента / виджета
  2. Улучшить содержание страницы
  3. Улучшение содержимого всей страницы (верхний колонтитул, контент, нижний колонтитул)

Улучшить один компонент / виджет:

Важное замечание: Указанные ниже методы улучшения должны использоваться только на текущей / активной странице. Для динамически вставленных страниц эти страницы и их содержимое будут улучшены после вставки в DOM. Вызов любого метода на динамически создаваемых страницах / кроме активной страницы приведет к ошибке.

Каждый виджет jQuery Mobile можно динамически улучшить:

  1. Listview:

    Улучшение разметки:

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

    Удаление элементов списка:

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

    Пример улучшения: http://jsfiddle.net/Gajotres/LrAyE/

    Обратите внимание, что метод refresh () влияет только на новые узлы, добавленные в список. Это сделано из соображений производительности.

    Одним из главных моментов списка является функциональность фильтрации. К сожалению, по какой-то причине jQuery Mobile не сможет динамически добавить опцию фильтра в существующий список. К счастью, есть обходной путь. Если возможно, удалите текущий просмотр списка и добавьте еще один с включенной опцией filer.

    Вот рабочий пример: /questions/4071714/jquery-mobile-ustanavlivaet-atribut-listview/4071718#4071718

    $(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. кнопка

    Улучшение разметки:

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

    Пример улучшения: http://jsfiddle.net/Gajotres/m4rjZ/

    Еще одна вещь, вам не нужно использовать элемент ввода для создания кнопки, это можно сделать даже с помощью базового div, вот пример: http://jsfiddle.net/Gajotres/L9xcN/

  3. Navbar

    Улучшение разметки:

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

    Пример улучшения: http://jsfiddle.net/Gajotres/w4m2B/

    Вот демонстрация того, как добавить динамическую вкладку панели навигации: http://jsfiddle.net/Gajotres/V6nHp/

    И еще одно событие в pagebecreate: http://jsfiddle.net/Gajotres/SJG8W/

  4. Текстовые вводы, поисковые входы и текстовые поля

    Улучшение разметки:

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

    Пример улучшения: http://jsfiddle.net/Gajotres/9UQ9k/

  5. Ползунки и флип-тумблер

    Улучшение разметки:

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

    Пример улучшения: http://jsfiddle.net/Gajotres/caCsf/

    Пример улучшения во время события pagebeforecreate: http://jsfiddle.net/Gajotres/NwMLP/

    Слайдеры немного глючат для динамического создания, подробнее об этом здесь: /questions/41558648/slajderyi-jquery-mobile-vstavlyayutsya-dinamicheski/41558659#41558659

  6. Флажок и Радиобокс

    Улучшение разметки:

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

    или если вы хотите выбрать / отменить выбор другого элемента Radiobox /Checkbox:

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

    или же

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

    Пример улучшения: http://jsfiddle.net/Gajotres/VAG6F/

  7. Выберите меню

    Улучшение разметки:

    $('select').selectmenu();  
    

    Пример улучшения: http://jsfiddle.net/Gajotres/dEXac/

  8. разборный

    К сожалению, складной элемент не может быть улучшен с помощью какого-то определенного метода, поэтому вместо него необходимо использовать триггер ('create').

    Пример улучшения: http://jsfiddle.net/Gajotres/ck6uK/

  9. Таблица

    Улучшение разметки:

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

    Хотя это стандартный способ улучшения таблиц, на данный момент я не могу заставить его работать. Поэтому вместо этого используйте триггер ("создать").

    Пример улучшения: http://jsfiddle.net/Gajotres/Zqy4n/

  10. Панели - Новые

    Улучшение разметки панели:

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

    Улучшение разметки содержимого, динамически добавляемого в Panel:

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

    Пример: http://jsfiddle.net/Palestinian/PRC8W/

Повысить содержание страницы:

В случае, если мы генерируем / перестраиваем весь контент страницы, лучше всего сделать все сразу, и это можно сделать с помощью этого:

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

Пример улучшения: http://jsfiddle.net/Gajotres/426NU/

Улучшение содержимого всей страницы (верхний колонтитул, контент, нижний колонтитул):

К сожалению, для нас триггер ('create') не может улучшить разметку верхнего и нижнего колонтитула. В этом случае нам нужны большие пушки:

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

Пример улучшения: http://jsfiddle.net/Gajotres/DGZcr/

Это почти мистический метод, потому что я не могу найти его в официальной документации jQuery Mobile. Тем не менее, его легко найти в трекере ошибок jQuery Mobile с предупреждением не использовать его, если это действительно не нужно.

Примечание .trigger('pagecreate'); можно предположить, что он используется только один раз для обновления страницы, я обнаружил, что это неправда:

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

Сторонние плагины улучшения

Есть несколько сторонних плагинов для улучшения. Некоторые сделаны как обновление существующего метода, а некоторые сделаны для исправления нарушенных функций jQM.

  • Изменение текста кнопки

    К сожалению не могу найти разработчика этого плагина. Исходный SO источник: Изменить текст кнопки 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);
    

    Рабочий пример: http://jsfiddle.net/Gajotres/mwB22/

Получите правильную максимальную высоту содержимого

В случае, если верхний и нижний колонтитулы страницы имеют постоянную высоту содержимого, div можно легко настроить так, чтобы он охватывал все доступное пространство небольшим трюком css:

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

И вот рабочий пример с Google maps api3 демо: http://jsfiddle.net/Gajotres/7kGdE/

Этот метод можно использовать для получения правильной максимальной высоты содержимого, и его необходимо использовать с событием pagehow.

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

А вот живой пример jsFiddle: http://jsfiddle.net/Gajotres/nVs9J/

Есть одна вещь, которую нужно запомнить. Эта функция будет корректно получать максимальную доступную высоту содержимого, и в то же время ее можно использовать для растягивания этого содержимого. К сожалению, его нельзя использовать для растягивания img до полной высоты содержимого, тег img имеет накладные расходы 3px.

Методы предотвращения повышения разметки:

Это можно сделать несколькими способами, иногда вам нужно будет объединить их для достижения желаемого результата.

  • Способ 1:

    Это можно сделать, добавив этот атрибут:

    data-enhance="false"
    

    в заголовок, содержимое, контейнер нижнего колонтитула.

    Это также необходимо включить на этапе загрузки приложения:

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

    Инициализируйте его до инициализации jquery-mobile.js (посмотрите на пример ниже).

    Подробнее об этом можно узнать здесь:

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

    Пример: http://jsfiddle.net/Gajotres/UZwpj/

    Чтобы заново создать страницу, используйте это:

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

    Второй вариант - сделать это вручную с помощью этой строки:

    data-role="none"
    

    Пример: http://jsfiddle.net/Gajotres/LqDke/

  • Способ 3:

    Некоторые элементы HTML могут быть предотвращены от улучшения разметки:

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

    Пример: http://jsfiddle.net/Gajotres/gAGtS/

    Снова инициализируйте его перед инициализацией jquery-mobile.js (посмотрите на пример ниже).

Проблемы улучшения разметки:

Иногда при создании компонента с нуля (например, просмотр списка) эта ошибка возникает:

не может вызвать методы на просмотр списка до инициализации

Это можно предотвратить с помощью инициализации компонента до улучшения разметки, вот как вы можете это исправить:

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

Проблемы с наложением разметки:

Если по какой-то причине необходимо изменить jQuery Mobile CSS по умолчанию, это должно быть сделано с !important переопределения. Без этого стили CSS по умолчанию не могут быть изменены.

Пример:

#navbar li {
    background: red !important;
}

jsFiddle пример: http://jsfiddle.net/Gajotres/vTBGa/

Изменения:

  • 01.02.2013 - Добавлена ​​динамическая демонстрация navbar
  • 01.03.2013 - Добавлен комментарий о том, как динамически добавлять фильтрацию в просмотр списка.
  • 07.03.2013 - Добавлена ​​новая глава: Получить правильную максимальную высоту контента
  • 17.03.2013 - Добавлено несколько слов в главу: получить правильную максимальную высоту контента
  • 29.03.2013 - Добавлен новый контент о динамически создаваемых слайдерах и исправлен пример ошибки
  • 03.04.2013 - Добавлен новый контент о динамически создаваемых складных элементах
  • 04.04.2013 - Добавлена ​​глава сторонних плагинов
  • 20.05.2013 - Добавлены динамически добавленные панели и содержимое.
  • 21.05.2013 - Добавлен еще один способ установки полной высоты содержимого
  • 20.06.2013 - Добавлена ​​новая глава: проблемы переопределения разметки
  • 29.06.2013 - Добавлено важное замечание КОГДА использовать методы улучшения

С JQMobile 1.4 вы можете делать.enhanceWithin() для всех детей http://api.jquerymobile.com/enhanceWithin/

var content = '<p>Hi</p>';
$('#somediv').html(content);
$('#somediv').enhanceWithin();
Другие вопросы по тегам