jQuery Mobile: Розмітка Покращення динамічно доданого вмісту


75

Мені цікаво, як я можу динамічно покращувати мобільну сторінку jQuery?

Я намагався використовувати ці методи:

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

    і

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

Також як я можу запобігти лише розмітці поліпшень для прапорців?


Що сталося, коли ви зробили .trigger ('create') для елемента, що містив елементи, які ви хотіли вдосконалити?
Джош

Відповіді:


165

Застереження:

Цю статтю також можна знайти як частину мого блогу ТУТ .

Вступ:

Існує кілька способів підвищення динамічно створеної розмітки вмісту. Просто недостатньо динамічно додавати новий вміст на сторінку jQuery Mobile , новий вміст повинен бути покращений класичним стилем jQuery Mobile . Оскільки це досить обробляюче важке завдання, потрібно мати певні пріоритети, якщо можливо, jQuery Mobile повинен зробити якомога менше посилення. Не покращуйте цілу сторінку, якщо потрібно стилізувати лише один компонент.

Що це все означає? Коли плагін сторінки відправляє подію pageInit , яку більшість віджетів використовують для автоматичної ініціалізації. він автоматично покращить усі екземпляри віджетів, які він знайде на сторінці.

Однак якщо ви генеруєте нову розмітку на стороні клієнта або завантажуєте вміст через Ajax і вводите його на сторінку, ви можете запустити подію create для обробки автоматичної ініціалізації для всіх плагінів, що містяться в новій розмітці. Це може бути спрацьовано на будь-якому елементі (навіть на самому div сторінки), що економить вам завдання ручної ініціалізації кожного плагіна (кнопка перегляду списку, вибір тощо).

З огляду на це давайте обговоримо рівні вдосконалення. Їх три, і вони відсортовані від менш вимогливих ресурсів до вищих:

  1. Покращення одного компонента / віджета
  2. Покращення вмісту сторінки
  3. Покращення повноцінного вмісту сторінки (заголовок, вміст, нижній колонтитул)

Покращення одного компонента / віджета:

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

Кожен віджет jQuery Mobile можна динамічно вдосконалювати:

  1. Перегляд списку :

    Покращення розмітки:

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

    Видалення елементів перегляду списку:

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

    Приклад вдосконалення: http://jsfiddle.net/Gajotres/LrAyE/

    Зверніть увагу, що метод refresh () впливає лише на нові вузли, додані до списку. Це робиться з міркувань продуктивності.

    Однією з найвищих точок списку є функція фільтрації. На жаль, з якихось причин jQuery Mobile не зможе динамічно додати параметр фільтра до існуючого перегляду списку. На щастя, є обхідний шлях. Якщо можливо, видаліть поточний перегляд списку та додайте ще один із увімкненою опцією файлу.

    Ось робочий приклад: 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. Кнопка

    Покращення розмітки:

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

    Приклад вдосконалення: http://jsfiddle.net/Gajotres/m4rjZ/

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

  3. Навбар

    Покращення розмітки:

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

    Приклад вдосконалення: http://jsfiddle.net/Gajotres/w4m2B/

    Ось демо-версія, як додати вкладку динамічної навігаційної панелі: http://jsfiddle.net/Gajotres/V6nHp/

    І ще одна у події pagebeforecreate : 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/

    Повзунки трохи глючать для динамічного створення, докладніше про це читайте тут: https://stackoverflow.com/a/15708562/1848600

  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");
    

    Хоча це стандартний спосіб покращення таблиці, на даний момент я не можу змусити це працювати. Тож замість цього використовуйте тригер ('create').

    Приклад вдосконалення: http://jsfiddle.net/Gajotres/Zqy4n/

  10. Панелі - нові

    Покращення розмітки панелі:

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

    Покращення розмітки вмісту, динамічно доданого до панелі:

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

    Приклад: http://jsfiddle.net/Palestinian/PRC8W/

Покращення вмісту сторінки:

Якщо ми генеруємо / відновлюємо вміст цілої сторінки, найкраще робити це відразу, і це можна зробити за допомогою цього:

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

Приклад вдосконалення: http://jsfiddle.net/Gajotres/426NU/

Покращення повноцінного вмісту сторінки (заголовок, вміст, нижній колонтитул):

На жаль для нас тригер ('створити') не може покращити розмітку верхнього та нижнього колонтитула. У цьому випадку нам потрібні великі гармати:

$('#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 має накладні витрати 3 пікселі.

Методи запобігання підвищенню розмітки:

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

  • Спосіб 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 (див. Приклад нижче).

Проблеми з покращенням розмітки:

Іноді при створенні компонента з нуля (наприклад, listview) виникає така помилка:

не може викликати методи в listview до ініціалізації

Цього можна запобігти ініціалізацією компонента до вдосконалення розмітки, ось як ви можете це виправити:

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

Проблеми перевизначення розмітки:

Якщо з якихось причин jQuery Mobile CSS потрібно змінити за замовчуванням, це потрібно зробити із !importantзаміною. Без цього стилі css за замовчуванням не можна змінити.

Приклад:

#navbar li {
    background: red !important;
}

jsFiddleприклад: http://jsfiddle.net/Gajotres/vTBGa/

Зміни:

  • 01.02.2013 - Додано динамічну демо-версію навігаційної панелі
  • 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 - Додано важливу примітку КОЛИ використовувати методи вдосконалення

1
@Gajotres Відмінне пояснення
Nikhil Agrawal

2
Якби я міг додати +6, це найкраща відповідь, яку я бачив за довгий час. Щиро дякуємо за це, тепер лише якщо документація для jQuery mobile була такою прямою. ДЯКУЮ! Хоча одне питання, у мене є заголовок, який я змінюю ... чи існує подібний метод для заголовка? $ (": jqmData (role = 'header')"). header ()?
Кріс

Якщо ви хочете покращити заголовок, вам потрібно використовувати тригер ('pagecreate'), ви можете знайти його в моїй відповіді.
Gajotres

Я хочу поліпшити поле введення за допомогою type = "password" Якщо я спробую $ ("# acntNewPW"). Textinput (); Я отримую класичний стиль, а за ним - новий мобільний стиль jquery.
alexander-fire

Зазвичай це відбувається, коли jQuery Mobile js не узгоджується з jQuery Mobile css. Перейдіть на їх офіційну сторінку та завантажте найновіші версії та повторіть спробу.
Gajotres

4

У JQMobile 1.4 ви можете зробити .enhanceWithin () для всіх дочірніх http://api.jquerymobile.com/enhanceWithin/

var content = '<p>Hi</p>';
$('#somediv').html(content);
$('#somediv').enhanceWithin();

Чи переважно це $('#somediv').trigger('create'), і якщо так, то чому?
Джош

.trigger ("створити") застаріло. Замість цього ви можете використовувати новий метод .enhanceWithin (). Наприклад, якщо ви динамічно додаєте розбірний із ul з data-role = "listview" всередині, ви можете використовувати .enhanceWithin () для ініціалізації плагіна listview.
zzart

Чи є проблемою викликати цей метод для елемента, діти якого вже вдосконалені?
Джош

Я не знаю про таку проблему. Однак цей метод застосовується всіма дітьми селектора і намагається вдосконалити все, що він може знайти. Обійти великі фрагменти DOM в деяких випадках не найшвидше, що можна зробити ...
zzart
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.