如何使用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 或<div>
s 的内部文本。通过这种方式,您没有冲突的 id 属性值,但您可以使用类占位符遍历 div
s 内的操作。
$('.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的load方法设计动态加载,并解决被加载页面JavaScript失效问题