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

时间:2010-09-14 01:03:34

标签: javascript jquery ajax jquery-ui

为atml加载并插入到文档中的html激活jquery ui小部件的最佳做法是什么?

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

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

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

或者使其更通用:

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

但是,我还想从动态加载的页面中激活javascripts,以便不同的小部件正常运行。

我知道,我可以将这些javascripts添加到当前文档中并在.load()的回调中激活所有这些javascripts,或者我可以使用$.get()分别获取一些带有html和javascripts的JSON,但是我想,可能会有更优雅的通用解决方案。

你会推荐什么?

顺便说一下,我在后端使用Django。

3 个答案:

答案 0 :(得分:1)

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

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

您可以考虑改变事物:

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

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

答案 1 :(得分:1)

我所做的是使用jquery.ui小部件可以指定的“load”选项。不幸的是,这没有详细记录,因此您不会在此处看到该选项:例如http://jqueryui.com/demos/tabs/#options,但您会在此处看到它:http://jqueryui.com/demos/tabs/#method-load

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

在我自己的应用程序中,我有3级嵌套选项卡,这些选项卡是通过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环境的相同情况的解决方案。我希望有所帮助!

答案 2 :(得分:0)

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

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

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

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

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

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