jQuery Gallery,单击页面更改后未触发的事件

时间:2014-11-11 01:21:27

标签: javascript jquery css pagination click

我正在开发一个jQuery Gallery,最近我添加了一个分页,发现尽管我的on('click')事件在最初调用显示功能时工作正常,但是一旦你改变页面(重新加载一个显示功能来显示)具有新的开始和结束变量的数组数据)我的on('click')事件停止工作。换回原始页面并不能再次使用。

我已尝试将.on("click")换成.click(),同时删除.empty()命令,以便页面继续向列表中添加新项目,以及其他一些更改,但我是仍然无法解决问题所在。

小提琴:http://jsfiddle.net/fw37y69h/

HTML

<div id="jGalContainer">
    <ul id="jGalImageList"></ul>

    <div id="jGalOverlay"></div>
    <div id="jGalDisplayOverlay"></div>
</div>

<button id="next">Next</button>
<button id="previous">Previous</button>

JS

$(document).ready(function(){

// Function that generates the display
var displayGal = function(start,stop) {
    // For each item between the passed start and stop variables, increment through the imgListArr array
    // And create the HTML dynamically within the jGalImageList div.
    for(var i = start; i < stop; i++) {
        $('#jGalImageList').append('<li id="image' + i + '"><div class="imgCont"><img id="' + imgListArr[i].id + '" src="' + imgListArr[i].thumbUrl + '" /></div><br /><span class="imageTitle">' + imgListArr[i].name + '</span>');
        console.log(imgListArr[i]);
   }
}

// Array of object items
var imgListArr = [
    {
        id: "image1",
        name: "Cute Puppy",
        url: "img/puppies.jpg",
        thumbUrl: "img/puppies-sm.jpg",
        description: "A lovely picture of a puppy."
    },
    {
        id: "image2",
        name: "Hungry Kitty",
        url: "img/kittens.jpg",
        thumbUrl: "img/kittens-sm.jpg",
        description: "Cats are okay I guess."
    },
    {
        id: "image3",
        name: "Mr Turtle",
        url: "img/turtles.jpg",
        thumbUrl: "img/turtles-sm.jpg",
        description: "All hail our new turtle overlords."
    },
    {
        id: "image4",
        name: "Magestic Deer",
        url: "img/deer.jpg",
        thumbUrl: "img/deer-sm.jpg",
        description: "Cats are okay I guess."
    },
    {
        id: "image5",
        name: "Duck Army",
        url: "img/ducks.jpg",
        thumbUrl: "img/ducks-sm.jpg",
        description: "All hail our new turtle overlords."
    },
    {
        id: "image6",
        name: "Sleepy Pelicans",
        url: "img/pelicans.jpg",
        thumbUrl: "img/pelicans-sm.jpg",
        description: "Cats are okay I guess."
    },
    {
        id: "image7",
        name: "Monkey Family",
        url: "img/monkeys.jpg",
        thumbUrl: "img/monkeys-sm.jpg",
        description: "All hail our new turtle overlords."
    },
    {
        id: "image8",
        name: "Sheeple",
        url: "img/sheep.jpg",
        thumbUrl: "img/sheep-sm.jpg",
        description: "Cats are okay I guess."
    },
    {
        id: "image9",
        name: "Monkey Family",
        url: "img/monkeys.jpg",
        thumbUrl: "img/monkeys-sm.jpg",
        description: "All hail our new turtle overlords."
    },
    {
        id: "image10",
        name: "Sheeple",
        url: "img/sheep.jpg",
        thumbUrl: "img/sheep-sm.jpg",
        description: "Cats are okay I guess."
    }
];

// Set number of items per page
var pageLength = 4;

// Calculate number of pages
var numPages = Math.ceil(imgListArr.length / pageLength);

// Check if the last page will be filled, and determine how many items will be
// displayed on the last page.
// If there is a remained when the array length is divided by number of items per page
// then grab how many items are to be left over and safe as lastPageItems.
// Else set the lastPageItems variable to be however many items are on a page because
// it should fit perfectly.
if(imgListArr.length % pageLength !=0) {
    lastPageItems = imgListArr.length % pageLength;
}
else {
    lastPageItems = pageLength;
}

// Check if there are multiple pages to set what is to be displayed, and set visibility
// of Next and Previous Buttons.
// If there is only one page, the start and stop variebles for the displayGal function
// are set to 0 and whatever the array length is because it will be 4 or less. If this
// the case then we hide the previous and next buttons because they are not needed.
// Otherwise we set the page variable to 0 to indicate we are starting on page 0 and
// then hide only the previous button, as we need the next button to progress through
// pages.
if(numPages === 1) {
    displayGal(0,imgListArr.length);
    $('#next').hide();
    $('#previous').hide();
}
else {
    var page = 0;
    displayGal(0,pageLength);
    $('#previous').hide();
}

// Event handler for clicking on an image to open up the image modal and the overlay
// When an image is clicked on then the we create a details variable to hold the
// array created by the populateModal variable. The function is passed the image ID
// for reference.
// The jGalOverlay (gray overlay) is set to be visible.
// HTML is added to the jGalDisplayOverlay (modal), which is an image and print out
// of the details, this will fade in over the top of the modal in 800ms.
// We grab the height of the window (viewport) and assign the jGalOverlay (gray
// overlay) to take up the whole length.
$('#jGalImageList>li>.imgCont>img').on('click',function(e){
    console.log("click");
    var details = populateModal(this.id);

    $('#jGalOverlay').show();

    $('#jGalDisplayOverlay').html('<img src="' + details[1] + '" id="' + this.id + 'id" alt="' + this.id + '" /><br /><p>' + details[3] + '</p>').fadeIn(800);

    var windowHeight = $(document).height() + "px";
    $('#jGalOverlay').css('height',windowHeight);
});

// Event handler for closing the image modal, if the background overlay is clickied on
// then hide the image modal and the overlay.
// We also use this opportunity to empty the jGalDisplayOverlay (modal) for next image
// click, not sure if this is neccessary for html() method, I was using apprend.
$('#jGalOverlay').on('click',function(e){
    $('#jGalDisplayOverlay').empty().hide();
    $('#jGalOverlay').hide();
});

// Event handler for when the next button is clicked to refresh what is being displayed
// When the next button is clicked, we increment the page variable.
// We test if the page is now 1, if it is we show the previous button, as page 1 can't
// be skipped, this means the show request is only called once rather than on each
// subsequent page load.
// We empty the jGalImageList div, this isn't neccessary if you want to grow a list of
// images but to achieve pages, we empty and then refresh the page.
// By grabbing the page number and multiplying it by page length we find what image
// we are up to viewing as a start point, then we test if we are on the last page, to
// determine if we need to use the lastPageItems variable yet, if we are on the last
// page then our new end variable is set to the number of items on the last page plus
// our new starting variable, and we hide the next button. Otherwise we just add the
// page length variable to the new starting variable to get our end point.
// We then call our display function to populate the jGalImageList.
$('#next').on('click',function(e) {
    page = page + 1;

    if(page == 1) {
        $('#previous').show();
    }

    $('#jGalImageList').empty();
    var newStart = page * pageLength;

    if(page == numPages - 1) {
        var newEnd = newStart + lastPageItems;
        $('#next').hide();
    }
    else {
        var newEnd = newStart + pageLength;
    }

    displayGal(newStart,newEnd);
});

// Event handler for when the previous button is clicked to refresh what is being
// displayed.
// First step is to decrement the page number we are on.
// We check if we are on the first page, if we are we rehide the previous button as
// we can't go back any further.
// We empty the jGalImageList so we can throw in our new image list.
// Our start point is calculated by multiplying page number by page length.
// We check if we are on a page other than the last one, if so we show the next
// button, this is so it is only called once, rather than every page decrement.
// A new end point is calculated by adding page length to our new start point, we
// don't need to worry about lastPageItems because you can't move backwards to the
// last page.
// We finish by calling our display function
$('#previous').on('click',function(e){
    page = page - 1;

    if(page == 0) {
        $('#previous').hide();
    }

    $('#jGalImageList').empty();
    var newStart = page * pageLength;

    if(page == numPages - 2) {
        $('#next').show();
    }

    var newEnd = newStart + pageLength;

    displayGal(newStart,newEnd);
});

// Function to populate the image modal that is displayed.
// We initialise a variable to determine if the image ID is found to false, and
// initialise an emtpy details array.
// We loop through the array, comparing IDs till we find a match.
// If we find a match, we set found to true, populate a details array with all the info
// from the imgListArray, and return details array.
// If no match is found, we return "Error", this will likely break the page, but should
// never actually be able to occur.
var populateModal = function(id) {
    var found = false;
    var details = [];
    for(var i=0; i < imgListArr.length; i++) {
        if(imgListArr[i].id === id) {
            var found = true;
            details = [imgListArr[i].name, imgListArr[i].url, imgListArr[i].thumbUrl,imgListArr[i].description]
            return details;
        }
    }
    if(found === false) {
        return "Error";
    }
}


});

CSS

#jGalContainer {
    width: 800px;
    border: 1px solid #ddd;
    background: #FAFAFA;
    margin: 0 auto;
}

#jGalImageList{
    width: 100%;
    list-style-type: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
}

#jGalImageList li {
    width: calc(49% - 20px);
    display: inline-block;
    *display: inline;
    zoom: 1;
    text-align: center;
    padding: 10px;
}

#jGalImageList li .imgCont {
    width: 100%;
    height: 180px;
    overflow: hidden;
}

#jGalImageList li img {
    width: 100%;
    overflow: hidden;
    margin-bottom: 5px;
    box-shadow: 1px 1px 1px #DEDEDE;
    -webkit-box-shadow: 1px 1px 1px #DEDEDE;
}

#jGalImageList li span.imageTitle {
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 14px;

}

#jGalDisplayOverlay {
    width: 800px;
    height: auto;
    border: 1px solid #777;
    background-color: #FAFAFA;
    display: none;
    position: fixed;
    top: 40px;
    left: calc(50% - 400px);
    z-index: 100;
}

#jGalDisplayOverlay img {
    width: 100%;
    border-bottom: 1px solid #777;
}

#jGalDisplayOverlay p {
    font-family: 'Source Sans Pro', sans-serif;
    font-size: 14px;
    padding: 10px;
}

#jGalOverlay {
    width: 100%;
    height: 100%;
    background: #333;
    opacity: 0.5;
    filter: (Opacity: 50);
    position: absolute;
    top: 0;
    left: 0;
    display: none;
    z-index: 1;
}

1 个答案:

答案 0 :(得分:1)

您目前所做的是直接将事件点击绑定到'#jGalImageList>li>.imgCont>img'

$('#jGalImageList>li>.imgCont>img').on('click',function(e){
    console.log("click");
    var details = populateModal(this.id);

    $('#jGalOverlay').show();

    $('#jGalDisplayOverlay').html('<img src="' + details[1] + '" id="' + this.id + 'id" alt="' + this.id + '" /><br /><p>' + details[3] + '</p>').fadeIn(800);

    var windowHeight = $(document).height() + "px";
    $('#jGalOverlay').css('height',windowHeight);
});

上面的事件处理程序只会在调用上面的代码时附加到所有#jGalImageList>li>.imgCont>img元素。由于您在单击“下一个”或“上一个”按钮时清空#jGalImageList并重新填充其内容,因此上面的事件处理程序在单击“下一个”或“上一个”按钮后不会起作用。

您还需要使用事件委派将click事件绑定到新创建的#jGalImageList>li>.imgCont>img元素。这是来自jQuery documentation

的摘要
  

事件委托允许我们将单个事件侦听器附加到父元素,该元素将为匹配选择器的所有后代触发,无论这些后代现在是存在还是将来添加。

以下是修改后的代码

$('#jGalImageList').on('click','li>.imgCont>img',function(e){
    console.log("click");
    var details = populateModal(this.id);

    $('#jGalOverlay').show();

    $('#jGalDisplayOverlay').html('<img src="' + details[1] + '" id="' + this.id + 'id" alt="' + this.id + '" /><br /><p>' + details[3] + '</p>').fadeIn(800);

    var windowHeight = $(document).height() + "px";
    $('#jGalOverlay').css('height',windowHeight);
});

这里有更新的小提琴:http://jsfiddle.net/fw37y69h/21/