如何使用jQuery解决动态加载页面中的重复对象?

Posted

技术标签:

【中文标题】如何使用jQuery解决动态加载页面中的重复对象?【英文标题】:How to solve duplicate objects in dynamic loading page by using jQuery? 【发布时间】:2010-12-13 09:29:21 【问题描述】:

我想解决动态加载内容中的重复对象。请看下面的源代码更容易理解。

带有 1 个动态加载内容的基本页面 HTML

<body>
     <div id="general-div"></div>>
     <div id="div1"></div>
     <div id="placeholder1">
          Dynamic Content will be placed inside this.

          <div class="inner-div"></div>
          <div class="div1"></div>
     </div>
</body>

对于本页标题中的脚本,很容易选择“general-div”对象,如下代码所示。

 $('#general-div')

在 placeholder1 中选择“inner-div”对象非常容易。所以我可以使用下面的代码进行选择。

 $('.inner-div')

上面的代码可以完美运行。但是,当同一文档中有多个重复对象(如以下 html)时,我无法使用上述代码。上面的代码将返回 2 个不是我想要的对象。

基本页面 HTML - 加载另一个动态加载内容后

<body>
     <div id="general-div"></div>>
     <div id="div1"></div>
     <div id="placeholder1">
          Dynamic Content will be placed inside this.

          <div class="inner-div"></div>
          <div class="div1"></div>
     </div>
     <div id="placeholder2">
          Dynamic Content will be placed inside this.

          <div class="inner-div"></div>
          <div class="div1"></div>
     </div>
</body>

可能的解决方案 1

我必须在动态加载内容中为每个脚本创建指定的 jQuery 对象,如下代码。

 // Deep copy for jQuery object.
 var specfiedjQueryObj = $.extend(true, , jQuery);

 // modify find function in jQuery object.
 specfiedjQueryObj.fn.find = function(selector)
 
      // by adding placeholder selector before eval result.
      return new specfiedjQueryObj.fn.old_find('#placeholder1 ' + selector);
 ;

 // So, I can select any object in dynamic loading content.
 (function($)
 
      // This result must be 1 object.
      $('.div1'); 
 )(temp);

尽管如此,这个解决方案应该很好用。但是我发现jQuery是一个非常复杂的对象。尝试使用时发现很多错误。

你有解决这个问题的想法吗?

PS.PlaceHolder Id 不是固定 Id。所以,不可能在选择器规则中修复它。此外,我不确切知道它在文档中的元素数量和位置(第一个、最后一个或中间)。因为动态加载内容会显示在很多页面上。

【问题讨论】:

您是否知道您需要选择的inner-div 的内容?它是独一无二的吗?根据此问题中的答案和 cmets 以及您的相关问题,要么 jQuery 不起作用,要么我们不了解您需要满足的业务规则和技术要求。 我认为你误解了 jQuery。例如,您看过 :first 吗? 【参考方案1】:

$('div[id^=placeholder]:last') 怎么样?

Selectors / attrubuteStartsWith

【讨论】:

我不知道它的确切数量。因此,在动态加载脚本中,不可能在每个选择器中指定顺序数。此外,它使我的脚本变得非常复杂。 你能详细说明你想要得到哪些元素吗?它们是如何附加的? :last 将始终获取最后一个元素 - 它不需要元素的索引。 我不知道文档中元素的确切数量和位置(第一个、最后一个或中间)。因为动态加载内容会显示在很多页面上。【参考方案2】:

您可以简单地使用$('.innerdiv:first') 获得first 1 或$('.inner-div:last') 获得last 1。或者,如果您有多个并且想要选择一个特定的 $('.inner-div:nth(x)'),其中 x 是项目的索引。

【讨论】:

我不知道它的确切数量。因此,在动态加载脚本中,不可能在每个选择器中指定顺序数。此外,它使我的脚本变得非常复杂。 请说明您的最终目标或预期解决方案是什么。你想隐藏所有重复的元素并只显示一个。你想改变一些css属性吗?您确定应该选择哪一个的标准是什么? 请看我可能的解决方案 1。这是这个问题的非常通用的解决方案。它不需要动态加载内容的位置。你有这样的想法吗?【参考方案3】:

以下函数将处理来自部分加载视图页面的数据,并为脚本中的每个 jQuery 选择器添加指定的上下文。这个答案效果很好。但是,它不支持外部脚本文件。

function renderPartialView(control, data)

    // For detecting all script tag in loaded data.
    var reExtractScript = /(<script type="text\/javascript">)([\s\S]+?)(<\/script>)/gi;

    // For detecting all "$" sign (must be jQuery object) in loaded data.
    var reFindDollarSign = /\$\(([\S]+?)\)/gi;

    // Find all matched string in loaded data.
    var result = reExtractScript.exec(data);
    var allScript = '';

    if (result)
    
        for (i = 0; i < result.length; i += 4)
           
            // Remove current script from loaded script.        
            data = data.replace(result[i], '');

            // Replace all "$" function by adding context parameter that is control.
            allScript += result[i+2].replace(reFindDollarSign, '$($1, "' + control + '")');
        
    

    // Load non-script html to control.
    $(control).html(data);

    // Evaluate all script that is found in loaded data.
    eval(allScript);


// This script will partially download view page from server in the same domain
$(function()

    $.get(getUrl('~/Profile/Section/ViewEducation'), null, function(data)
    
        // When partial loading is complete, all loaded data will be sent to “renderPartialView” function
        renderPartialView('#education-view', data);
    );
);

【讨论】:

【参考方案4】:

好的,让我们谈谈您的示例 HTML。我添加了一个占位符类,并在 id 中添加了一个破折号以方便以后使用。

<div id="placeholder-1" class="placeholder">
     Dynamic Content will be placed inside this.

     <div class="inner-div">baz</div>
     <div class="div1">zip</div>
     <a href="#" class="action">action</a>
</div>
<div id="placeholder-2" class="placeholder">
     Dynamic Content will be placed inside this.

     <div class="inner-div">foo</div>
     <div class="div1">bar</div>
     <a href="#" class="action">action</a>
</div>

现在我可以使用$('.placeholder a.action').bind('click', ... ); 将一个事件绑定到每个链接上

此代码会将事件附加到这些链接,var 语句可以捕获 id 或&lt;div&gt;s 的内部文本。通过这种方式,您没有冲突的 id 属性值,但您可以使用类占位符遍历 divs 内的操作。

$('.placeholder a.action').live('click', function()
    // get the id
    var id = $(this).parents('div.placeholder').attr('id').split('-')[1];
    // get the text inside the div with class inner-div
    var inner_div = $(this).parents('div.placeholder').children('.inner-div').text();
    // get the text inside the div with class div1
    var div1 = $(this).parents('div.placeholder').children('.div1').text();
    return false;
);

【讨论】:

我认为您的答案应该适用于我的示例。但是,对于您的脚本来说非常复杂。我认为您的脚本必须放在我不喜欢的父文档中。因为我不能在另一个页面中重用它。请看我的回答。您有什么想法或建议吗? 为了澄清我的问题,您可以将动态加载页面想象成一些复杂的控件,如日历或网格视图。您可以在同一页面上拥有多个控件。此外,所有这些控件都将根据点击等用户操作加载和显示数据。因此,您的想法不应该是解决我的问题的最佳方法,主要关注以下三点:易于使用、易于重用、易于修改。感谢您提出您的答案。 我不明白你反对我的剧本。 当我尝试通过 AJAX 在同一个网页中加载两个局部视图页面时,ASP.NET MVC 会导致原始问题。我在每个部分视图页面中都有脚本。因此,jQuery 选择器将无法正常工作。在指定的对象案例 ID 中,jQuery 将返回第一个匹配的对象。另一方面,如果没有指定对象的 ID,jQuery 将从两个重复的局部视图页面返回所有匹配的对象。正如我之前评论的那样,您的答案对于我的示例可能很好。尽管如此,您的脚本被设计为包含在父页面中,而不是像我一样包含在部分视图页面中。 我已在您的问题中添加了与 asp.net 相关的标签,因此也许 asp.net maven 能够提供帮助。但听起来你想要的是默认情况下不包含处理这些部分视图的代码。也许你需要的是依赖注入,当这些部分视图被加载以调用任何必要的 JS 以使用$.getScript 处理它们时。

以上是关于如何使用jQuery解决动态加载页面中的重复对象?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Mobile 如何通过ajax方式动态加载页面?

jQuery动态加载select下拉列表

使用jquery load遇到一个问题解决

使用jquery的load方法设计动态加载,并解决被加载页面JavaScript失效问题

jquery easyui datagrid在进行初始化页面加载的时候,如何数据没有加载完毕,动态加载数据.

用于加载联系人的Phonegap Jquery Pagination - 当用户到达最后一页时如何动态添加页面?