如何部分和逐步迭代javascript对象?

时间:2011-02-28 18:35:25

标签: javascript jquery json api flickr

我正在使用jQuery和Flickr API来返回一个json对象,其中包含来自用户照片流的许多照片。

我想迭代生成的对象,最初显示40张照片,然后是“加载更多”按钮。每次单击该按钮时,下一批40张照片将附加到现有照片列表中。一旦对象中没有其他项目,该按钮就会返回到用户的Flickr配置文件的超链接。

目前,我有工作代码显示前40张照片。但是当点击“加载更多”按钮时,我将所有剩余的项目添加到HTML中。这是因为我无法找到产生上述行为的方法。

也许我还错过了一种更有效的方法。

这是我现有的代码。任何其他评论或改进都是最受欢迎的。

$(function () {
    myApp.uri = myApp.flickrUrl + '&per_page=' + myApp.maxNum + '&api_key=' + myApp.flickrApiKey + '&user_id=' + myApp.flickrUserId;

    myApp.getPhotos(myApp.uri, myApp.callback);
});

var myApp = {
    flickrApiKey : 'xxxx',
    flickrUserId : 'xxxx',
    flickrUrl : 'http://api.flickr.com/services/rest/?format=json&extras=url_t&method=flickr.people.getPublicPhotos',
    callback : 'jsonFlickrApi',
    minNum : 40,
    maxNum : 500
};

myApp.getPhotos = function (u, c) { 
    var jxhr = $.ajax({
        dataType : 'jsonp',
        url : u,
        jsonpCallback : c,
        timeout : 5000
    })

    .success(function (data, status) { 
        var photosContainer = $('#photos');
        photosContainer.prepend('<ul/>');
        var photosList = $('#photos ul');

        // while there are more photos to load, the default link text
        // is replaced with a string stored in a data-* attribute
        var moreLink = $('#more');
        var moreLinkText = moreLink.text();
        var moreLinkTextJs = moreLink.attr('data-text-js');
        moreLink
         .attr('data-text-nojs', moreLinkText)
         .text(moreLinkTextJs)
         .insertAfter(photosContainer);

        // initially populate the Photo List with the first 40 photos
        $.each(data.photos.photo, function (i, item){
            if (i < myApp.minNum) {
                var photoEl = '<li><a href="' + 'http://www.flickr.com/photos/' + item.owner + '/' + item.id + '" target="_blank"><img src="' + item.url_s + '" alt="' + item.title + '"></a></li>';
                $(photoEl).appendTo(photosList);
            }
        });

        // click on "More" link loads in all remaining photos.
        // would like this to load the next 40 in the object
        // each click until there are no items left...at which point unbind
        moreLink.live('click', function (e) {
            e.preventDefault();
            $.each(data.photos.photo, function (i, item){
                if (i >= myApp.minNum) {
                    var photoEl = '<li><a href="' + 'http://www.flickr.com/photos/' + item.owner + '/' + item.id + '" target="_blank"><img src="' + item.url_s + '" alt="' + item.title + '"></a></li>';
                    $(photoEl).appendTo(photosList);
                } 
            });

            // unbind events and revert the link text
            moreLink.text(moreLinkText).blur().die();
        });
    })

    .error(function (status) { 
    });
};

2 个答案:

答案 0 :(得分:1)

我建议查看模板

http://api.jquery.com/category/plugins/templates/

您实际上只需将JSON传递给模板并附加它即可。你的代码中没有循环:-)

这是一个教程:

http://www.borismoore.com/2010/09/introducing-jquery-templates-1-first.html

编辑:

要将返回的JSON修改为40个照片块,请在data.photos数组中使用array.slice方法

这样的东西
var number_of_blocks = Math.floor(data.photos / 40)
var blocks = [];
var last_block_starts_at = number_of_blocks * 40;

for (var i = 0 ; i < number_of_blocks ; i++;)
{
blocks << data.photos.slice(i,40+i);
}
blocks << data.photos.slice(last_block_starts_at);

现在你可以遍历块,直到数组结束......

答案 1 :(得分:0)

我从我的一个页面获得了此代码。我想这就像你想要的那样。对不起,行没有记录。但我确定你可以从中提取逻辑。

function photoLookUp(btn, ImageToUpdateId, LookUpWindowId, ImageContainerId, ImageSize) {

    var wnd = $(LookUpWindowId);
    if (wnd.active) return (wnd.style.display == "none") ? show() : hide();

    var wndResize = wnd.children[1].children[0];
    var ImageToUpdate = $(ImageToUpdateId);
    var imgContainer = $(ImageContainerId); imgContainer.innerHTML = "";

    wndResize.onmousedown = resizeOnMouseDown;
    wnd.onmousemove = function (e) { wnd.tHide = false }
    wnd.onmouseout = function (e) { wnd.tHide = true }
    wnd.active = true;

    var ldr = document.createElement("img");
    ldr.src = "Images/preloader.gif";
    ldr.title = "Loading, please wait...";
    ldr.onmouseover = function (e) { wnd.tHide = false }
    imgContainer.appendChild(ldr);

    show();

    var svc = new WADService();
    var par = { UserID: User.Profile.UserID };
    var dat = svc.get("GetUserPhotos", false, par);

    if (dat.length > 0)
        load(dat.shift(), 15);
    else
        imgContainer.innerHTML = "no photo collection";

    function load(Photo, cnt) {
        var par = { ImageID: Photo.ImageID, ImageSize: ImageSize };
        svc.get("GetImageURL", true, par).onreadystatechange = function (e) {
            if (this.readyState == 4) {
                var res = svc.deserialize(this.responseText);
                if (res) render(res);
            }
        }
        function render(res) {
            Photo.ImageURL = res;
            var obj = new PhotoObj(Photo).frameElement;
            imgContainer.insertBefore(obj, ldr)
            if (dat.length > 0 && --cnt > 0) {
                ldr.onclick = null;
                ldr.src = "Images/preloader.gif";
                ldr.title = "Loading, please wait...";
                load(dat.shift(), cnt)
            } else if (dat.length > 0) {
                ldr.onclick = loadMore;
                ldr.src = "Images/ViewPhoto.png";
                ldr.title = "View more...";
                //none of the ff lines work, ugh! how can i scroll my div in firefox ?!?!
                //imgContainer.scroll(0, imgContainer.scrollHeight - imgContainer.clientHeight);
                //imgContainer.scroll(0, imgContainer.scrollHeight);
            } else {
                imgContainer.removeChild(ldr);
            }
        }
        function loadMore(e) {
            ldr.onclick = null;
            load(dat.shift(), 16);
        }
    }
    function show() {
        wnd.style.display = "inline-block";
        btn.children[0].src = "Images/ArrowU.gif";
        wnd.tHide = true;
        wnd.tInterval = setInterval(_hide, 2000);
        function _hide(e) {
            if (wnd.tHide) { clearInterval(wnd.tInterval); hide() }
        }
    }
    function hide(e) {
        wnd.style.display = "none";
        btn.children[0].src = "Images/ArrowD.gif";
    }
    function resizeOnMouseDown(e) {
        var X = e.clientX, Y = e.clientY;
        var W = imgContainer.offsetWidth, H = imgContainer.offsetHeight;
        wndResize.style.cursor = "se-resize";
        document.onmousemove = function (e) {
            imgContainer.style.width = Math.max(72, (W + e.clientX - X)) + "px";
            imgContainer.style.height = Math.max(72 + 16, (H + e.clientY - Y)) + "px";
            return false;
        }
        document.onmouseup = function (e) {
            document.onmousemove = null; document.onmouseup = null;
            wndResize.style.cursor = "default";
        }
        return false;
    }
    function PhotoObj(Photo) {
        var img = document.createElement("div");
        this.frameElement = img;
        img.title = Photo.Title;
        img.ImageID = Photo.ImageID;
        img.ImageURL = Photo.ImageURL;
        img.style.backgroundImage = "url(" + Photo.ImageURL + ")";
        img.onmouseover = function (e) { wnd.tHide = false }
        img.onclick = function select(e) {
            ImageToUpdate.ImageID = img.ImageID;
            ImageToUpdate.ImageURL = img.ImageURL;
            ImageToUpdate.style.backgroundImage = img.style.backgroundImage;
            hide();
        }
    }
}