代码之家  ›  专栏  ›  技术社区  ›  Aidas Bendoraitis Rob Sanderson

在动态加载表单中激活jquery UI小部件

  •  2
  • Aidas Bendoraitis Rob Sanderson  · 技术社区  · 15 年前

    对于通过Ajax加载并插入到文档中的HTML,激活jquery ui小部件的最佳实践是什么?

    我是一个不引人注目的javascript的倡导者,我坚信javascript访问的所有功能也应该可以在没有它的情况下访问。因此,在理想情况下,在弹出窗口中打开的每个表单都应该有其单独的页面,并且到这些页面的链接应该替换为基于javascript的Ajax加载。

    我发现这个模式对于在当前文档中加载和插入另一个页面的一部分非常有用:

    $('#placeholder').load('/some/path/ #content>*');
    

    或者使其更通用:

    $('a.load').each(function() {
        $(this).load($(this).attr('href') + ' #content>*');
    });
    

    但是,我还希望从动态加载的页面激活javascripts,以便不同的小部件正常工作。

    我知道,我可以将这些javascript添加到当前文档中,并在 .load() 或者我可以用 $.get() 要分别使用HTML和JavaScript获得一些JSON,但我想,可能会有一个更优雅的通用解决方案。

    你会推荐什么?

    顺便说一句,我在后台使用django。

    3 回复  |  直到 15 年前
        1
  •  1
  •   koblas    15 年前

    问题是你目前是如何激活你的javascript的。如果你在做类似的事情:

    $(document).ready(function() {
          $('a.foo').click(function() { ... });
      })
    

    您可以考虑将事情更改为:

    $(document).ready(function() {
          $('a.foo').live('click', function() { ... });
      })
    

    这样,当加载新的DOM对象时,事件处理程序将被附加。

        2
  •  1
  •   Michael Merchant    15 年前

    我所做的是使用jquery.ui小部件指定的“加载”选项。不幸的是,这没有很好的文档记录,因此您在这里看不到选项: http://jqueryui.com/demos/tabs/#options 例如,但您将在此处看到: http://jqueryui.com/demos/tabs/#method-load

    在大多数情况下,您调用的每个方法都有一个可以设置的初始选项,这正是促使我尝试使用加载的原因。

    在我自己的应用程序中,我有三个层次的嵌套选项卡,它们是通过Ajax动态创建的。为了动态地应用每个选项卡的javascript,我有嵌套的加载函数,这些函数在加载文档时首先启动。

    所以我的模板文件有:

    <script type="text/javascript" src="{{ MEDIA_URL }}js/tabs.js"></script>
    <script type="text/javascript">
    $(function() {  
        $('.overall_tabs').tabs({
            load: initializeOverallTabs
        });
    });
    </script>
    

    我的tabs.js文件有:

    function initializeOverallTabs(event, ui){
        ...
        $('.lvl_two_tabs').tabs({
            load: initializeTabLevel2
        });
        ...
    }
    
    function initializeTabLevel2(event, ui){
        ...
        // So on and so forth
        ...
    }
    

    另外,我建议在加载区域内工作时,使您的引用特定于该窗格。这在处理选项卡时非常重要。我发现最好的方法是下面。

    在tabs.js文件中:

    function initializeOverallTabs(event, ui){
       $panel = $(ui.panel);
       $panel.find('lvl_two_tabs').tabs(...);
    }
    

    我发现这个问题出奇地巧合!我最近向几个开发人员解释了我的解决方案,让他们了解相同的jquery/django环境下的相同情况。希望有帮助!

        3
  •  0
  •   Aidas Bendoraitis Rob Sanderson    15 年前

    我决定自己处理来自外部页面的小部件的一种方法是解析另一个页面的HTML,搜索脚本并在当前页面中执行它们。

    例如,在另一个页面上有一个带有自动完成小部件的表单,它被加载并插入到该页面。自动完成小部件应使用特定属性激活,如可用选项:

    <script type="text/javascript">
    //<![CDATA[
    $(function() {
        $("#colors").autocomplete({
            source: ['red', 'green', 'blue', 'magenta', 'yellow', 'cyan']
        });
    });
    //]]>
    </script>
    

    然后在当前页面中,我可以使用以下脚本加载HTML,并另外收集其中的所有javascript并执行它们:

    var oRe = /<script\b[^>]*>([\s\S]*?)<\/script>/gm;
    $('#placeholder').load(
        '/some/path/ #content>*',
        function(responseText, textStatus, XMLHttpRequest) { // <-- callback function
            var sScripts = "";
            responseText.replace(
                oRe,
                function($0, $1) {
                    sScripts += $1;
                    return $0;
                }
            );
            eval(sScripts);
        }
    );
    

    这里的一个缺点是,当前文档最初应该加载可能出现在所包含表单中的所有库。例如,在本例中,它是包含自动完成小部件的jQueryUI。我想我可以通过搜索加载外部脚本的脚本标记来扩展代码,并在当前文档中加载它们(如果它们不存在的话)。