开发者

Get one script to cycle through multiple variables

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 then appendTo()


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()

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜