jQuery Mobile:动态添加内容的标记增强


75

我想知道如何动态增强jQuery Mobile页面?

我尝试使用以下方法:

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

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

另外,如何仅阻止复选框的增强标记?


当您对包含要增强的元素的元素执行.trigger('create')时会发生什么?
2014年

Answers:


165

免责声明:

本文也可以在我的博客HERE中找到

介绍:

有几种增强动态创建的内容标记的方法。将新内容动态添加到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选项的列表视图。

    这是一个工作示例: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. 可折叠

    不幸的是,可折叠元素无法通过某些特定方法进行增强,因此必须使用trigger('create')来代替。

    增强示例:http : //jsfiddle.net/Gajotres/ck6uK/

  9. 标记增强:

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

    尽管这是表增强的标准方法,但目前无法使它起作用。因此,请使用trigger('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/

增强整个页面的内容(页眉,内容,页脚):

对我们来说不幸的是,trigger('create')无法增强页眉和页脚标记。在这种情况下,我们需要大枪:

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

增强示例:http : //jsfiddle.net/Gajotres/DGZcr/

这几乎是一个神秘的方法,因为在官方jQuery Mobile文档中找不到它。仍然很容易在jQuery Mobile Bug Tracker中找到它,并警告不要使用它,除非确实有必要。

注意,.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/

获取正确的最大内容高度

如果页面的页眉和页脚具有恒定的高度,则可以使用一些CSS技巧轻松地将div设置为覆盖全部可用空间:

#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/

此方法可用于获取正确的最大内容高度,并且必须与pageshow事件一起使用。

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之前,再次对其进行初始化(请看下面的示例)。

标记增强问题:

有时,从头开始创建组件时(例如listview),会发生此错误:

初始化之前无法在listview上调用方法

可以通过在标记增强之前进行组件初始化来防止此问题,这是解决此问题的方法:

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

标记覆盖问题:

如果出于某种原因需要更改默认的jQuery Mobile CSS,则必须使用!important重写来完成。没有它,默认的CSS样式将无法更改。

例:

#navbar li {
    background: red !important;
}

jsFiddle示例:http//jsfiddle.net/Gajotres/vTBGa/

变化:

  • 2013年1月2日-添加了动态导航栏演示
  • 01.03.2013-添加了有关如何向列表视图动态添加过滤的注释
  • 2013年3月7日-添加了新章节:获取正确的最大内容高度
  • 2013年3月17日-在本章中添加了一些文字:获取正确的最大内容高度
  • 2013年3月29日-添加了有关动态创建的滑块的新内容并修复了示例错误
  • 2013年3月4日-添加了有关动态创建的可折叠元素的新内容
  • 04.04.2013-添加了第3方插件章节
  • 20.05.2013-添加了动态添加的面板和内容
  • 2013年5月21日-添加了另一种设置完整内容高度的方法
  • 2013年6月20日-添加了新的章节:标记覆盖问题
  • 29.06.2013-添加了何时使用增强方法的重要说明

1
@Gajotres出色的解释
Nikhil Agrawal

2
希望我可以加上+6,这是我很长时间以来看到的最好的答案。非常感谢您,现在,仅当jQuery mobile的文档非常简单时。谢谢!但是有一个问题,我有一个要更改的标题...标题是否有类似的方法?$(“:jqmData(role ='header')”)。header()?
克里斯(Chris)

如果要增强标题,则需要使用trigger('pagecreate'),可以在我的答案中找到它。
Gajotres

我想用type =“ password”增强输入字段,如果我尝试$(“#acntNewPW”)。textinput(); 我得到了经典风格,然后有了新的jquery移动风格。
亚历山大大火

当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'),如果可以,为什么?
2014年

.trigger(“ create”)已被弃用。您可以改用新方法.enhanceWithin()。例如,如果您动态添加一个带有ul且带有data-role =“ listview”的ul折叠器,则可以使用.enhanceWithin()来初始化listview插件。
zzart 2014年

在子元素已经得到增强的元素上调用此方法是否有问题?
2014年

我不知道这样的问题。但是,此方法遍历选择器的所有子级,并尝试增强它可以找到的任何内容。在某些情况下,遍历大块DOM并不是最快的事情……
zzart 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.