How to solve duplicate objects in dynamic loading page by using jQuery?
I want to solve duplicate objects in dynamic loading content. Please look at the following source code for easier understand.
Base Page HTML With 1 Dynamic Loading Content
<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>
For script in header of this page, it's very easy to select "general-div" object like the following code.
$('#general-div')
It's quite easy for select "inner-div" object inside placeholder1. So I can select by using the below code.
$('.inner-div')
The above code could works perfectly. However, I can't use the above code when there is more than 1 duplicated object in the same document like the following HTML. The above code will return 2 objects that don’t what I want.
Base Page HTML - After load another dynamic loading content
<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=&开发者_C百科quot;placeholder2"> Dynamic Content will be placed inside this. <div class="inner-div"></div> <div class="div1"></div> </div> </body>
Possible Solution 1
I must create specified jQuery object foreach script in dynamic loading content like the following code.
// 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);
Even though, this solution should be work great. But I found that jQuery is a very complex object. I found a lot of errors when I try to use it.
Do you have any idea for solving this problem?
PS.PlaceHolder Id is not a fixed Id. So, It's impossible to fixed it in selector rule. Moreover, I do not know exactly amount of element and position (first, last or middle) of it in document. Because of dynamic loading content will be displayed on a lot of page.
How about $('div[id^=placeholder]:last')
?
Selectors / attrubuteStartsWith
You could simply use $('.innerdiv:first')
to get the first one or $('.inner-div:last')
to get the last one. Or if you have multiples and want to select a particular one $('.inner-div:nth(x)')
where x is the index of the item.
The following function will process data from partial loading view page and add specified context for each jQuery selector in script. This answer works well. However, it does not support external script file.
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);
});
});
Okay, so let's talk about your example HTML. I added a class of placeholder, and added a dash in the id for convenience later.
<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>
Now I can bind an event to each of these links with $('.placeholder a.action').bind('click', ... );
If I want this event to all future chunks of html like this on the page, I do $('.placeholder a.action').live('click', ... );
This code will attach an event to those links and the var
statements can capture the id, or the inner text of the <div>
s. In this way you don't have colliding id attribute values, but you can traverse actions inside div
s with class placeholder.
$('.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;
});
精彩评论