I have a page that rates the top 15 websites one the web (from Alexa), and it uses javascript to write the new ratings, but this is very inefficient. There are 6 variables for each rating. And it writes one code block for each rating, using the variables. Is there a way to just make it use one code block to write all 15 of the ratings? Here is some code:
var topID1 = 1;
var topWidth1 = 100;
var topPageURL1 = 'www.google.com'
var topPageTitle1 = 'Google';
var topRate1 = rateStar9;
var topMargin1 = 0;
$('#topSites1').html('<div class="meter-wrap" style="margin-top: ' + topMargin1 + 'px;">开发者_高级运维<div class="meter-value" style="background-color: ' + topSitesBack + '; width: ' + topWidth1 + '%;"><div class="meter-text"><span class="toplist"><span class="topnum">' + topID1 + '. </span><span class="favico" id="ico1"><img src="img/blank.gif" style="width:16px;height:16px;"></img></span><a href="http://' + topPageURL1 + '/">' + topPageTitle1 + '</a><span class="rating" style="width: ' + topRate1 + 'px;"><img src="img/blank.gif" style="width:100%;height:16px;"></img></span></span></div></div></div>');
$('#ico1').css('background', 'url(' + topPageFavicon + topPageURL1 + ') no-repeat');
(repeat both 15 times)
Its called using a javascript object. than you can itterate through the object to get you info:
var all_ratings = {
'GOOGLE': {
topID: 1,
topWidth: 100,
topPageURL: 'something',
topPageTitle: 'something_else',
topRate: rateStar,
topMargin: 'something'
},
'YAHOO': {
topID: 1,
topWidth: 100,
topPageURL: 'something',
topPageTitle: 'something_else',
topRate: rateStar,
topMargin: 'something'
},
..MORE
}
Than you can do (using $.each
): (since i believe you are using jQuery):
$.each(all_ratings, function (index, item)
{
var outerDiv = $('<div>', {
'class': 'meter-wrap',
style: 'margin-top: ' + item.topMargin + 'px;'
}),
innerDiv = $('<div class="meter-value" style="background-color: ' + topSitesBack + '; width: ' + item.topWidth + '%;">').html('<div class="meter-text"><span class="toplist"><span class="topnum">' + item.topID + '. </span><span class="favico" id="ico1"><img src="img/blank.gif" style="width:16px;height:16px;"></img></span><a href="http://' + item.topPageURL + '/">' + item.topPageTitle + '</a><span class="rating" style="width: ' + item.topRate + 'px;"><img src="img/blank.gif" style="width:100%;height:16px;"></img></span></span></div>');
innerDiv.appendTo(outerDiv);
$('#topSites').append(outerDiv);
})
fiddle: http://jsfiddle.net/maniator/QWAhV/
side note: instead of using topPageTitle
you can just use the index
variable which will return the page you are up to, like 'GOOGLE' , or 'YAHOO', fiddle for that: http://jsfiddle.net/maniator/QWAhV/8/
Manipulating the DOM that heavily is known to be pretty slow. You can try things like:
- cache your reference to
$('#topSites1')
so jQuery doesn't have to search for it every time. - Detach the node from the DOM, add your stuff to it, then re-attach it when it's ready. This will reduce a lot of DOM refreshes and possibly will show a decent performance improvement. To do this you need to use jQuery methods
detach()
and thenappendTo()
Lets clean it with OO, old school style.
First, define a TopEntry "class":
function TopEntry(id, width, pageURL, pageTitle, rate, margin, sitesBack, pageFavicon) {
this.id = id;
this.width = width;
this.pageURL = pageURL;
this.pageTitle = pageTitle;
this.rate = rate;
this.margin = margin;
this.sitesBack = sitesBack;
this.pageFavicon = pageFavicon;
this.createDiv = function() {
return $('<div class="meter-wrap" style="margin-top: ' + this.margin + 'px;"><div class="meter-value" style="background-color: ' + this.sitesBack + '; width: ' + this.width + '%;"><div class="meter-text"><span class="toplist"><span class="topnum">' + this.id + '. </span><span class="favico" id="ico' + this.id + '"><img src="img/blank.gif" style="width:16px;height:16px;"></img></span><a href="http://' + this.pageURL + '/">' + this.pageTitle + '</a><span class="rating" style="width: ' + this.rate + 'px;"><img src="img/blank.gif" style="width:100%;height:16px;"></img></span></span></div></div></div>')
}
}
Then, lets declare an array and instantiate some TopEntry objects:
// create some array
var sites = new Array();
// Create object
var site = new TopEntry(1, 100, 'www.google.com', 'Google', rateStar9, 0, 'white', 'http://www.google.com/favicon.ico');
// push the object into the array
sites.push(site);
And finally the code to append the divs (considering that you are doing it at loading time):
// Manipulate DOM: Following Neal append Approach
$(document).ready(function(){
$.each(sites, function (index, item) {
$('#topSites').append(item.createDiv());
$('#ico' + item.id).css('background', 'url(' + item.pageFavicon + ') no-repeat');
});
});
As for the markup, all you need is a div acting as a container:
<div id="topSites"></div>
And of course, no javascript answer is ever complete without jsfiddle: http://jsfiddle.net/Q8duz/2/
Well, this is it ;).
You need to use a loop by using the each function: jquery .each()
精彩评论