2016-06-30 6 views
1

У меня есть проект, над которым я работаю, у которого есть галерея. Как работает галерея, пользователь получает список изображений, и каждое изображение является «альбомом», который ссылается на большее количество изображений для данной галереи. В настоящее время я работаю, но когда пользователь нажимает кнопку «Назад» после перехода в выбранную галерею, они не возвращаются к списку альбомов. Например, если вы являетесь главной страницей, нажмите на страницу альбомов и откройте галерею. После нажатия кнопки «Назад» вы вернетесь на домашнюю страницу.Добавление pushState() и popstate в мой проект

Итак, я решил исправить это, я могу использовать историю api и использовать pushState и popstate. Моя проблема в том, что я не смог заставить ее работать, и я не уверен, где разместить функции в моем сценарии.

Если вы хотите у меня есть живая версия сайта я работаю здесь: Live Demo

Вот мой текущий сценарий:

(function(code) { 
    code(window.jQuery, window, document); 
}(function($, window, document) { 
    $(function() { 
    initialize(); 
    }); 

    function initialize() { 
    $.getJSON('/assets/js/images.json', function(json) { 
     $.each(json.albums, function(i, item) { 
     var photos = item.photos, 
      name = item.name, 
      id  = item.id; 

     showAlbums(photos, name, id); 
     }); 
    }); 
    } 
    function showAlbums(p, n, i) { 
    var albums = $('.albums'), 
     gallery = $('.gallery'), 
     album  = $('#templates #album .thumb').clone(true), 
     thumbnail = album.find('.thumbnail'), 
     image  = album.find('.image'), 
     caption = album.find('.caption h4'); 

    thumbnail.attr('href', '#').attr('title', n).attr('data-url', i); 
    image.attr('src', p[0].href).attr('alt', n); 
    caption.html(n); 

    albums.append(album); 

    album.on('click', 'a', function(e) { 
     e.preventDefault(); 
     albums.hide(); 
     gallery.empty().show(); 
     document.title = "Schultz | " + n; 
     $.each(p, function(i, item) { 
     var photo = item.href; 
     showGallery(photo, n); 
     }); 
    }); 
    } 
    function showGallery(p, n) { 
    var gallery = $('.gallery'), 
     images = $('#templates #gallery .thumb').clone(), 
     link = images.find('.thumbnail'), 
     image = images.find('.thumbnail img'); 

    link.attr('href', p).attr('title', n).attr('data-gallery', ''); 
    image.attr('src', p).attr('alt', n); 

    gallery.append(images); 
    } 
})); 

Любая помощь приветствуется, спасибо

+0

Нет времени, чтобы вступить в полный ответ здесь, но то, что вы хотите сделать, - это реорганизовать обработчик кликов вашего альбома в функцию showAlbum, которая, вместо того, чтобы зависать от локальных переменных в области, принимает в индексе или идентификатор альбома данные JSON (которые вы должны поддерживать ссылку вместо того, чтобы просто использовать init, чтобы вы могли использовать ее позже). При щелчке альбома вы затем «pushState» добавили новый URL-адрес «id =« + id », а затем« showAlbum (id) »для загрузки представления. Затем в 'window.onpopstate' вы вытащите' id' из строки запроса и 'showAlbum (id)'. – numbers1311407

+0

Тогда, конечно, если в строке запроса нет 'id', вы просто спрячете' gallery' и покажете «альбомы» (случай, когда пользователь нажимает «назад» в представлении галереи). В пользовательском интерфейсе вы, вероятно, захотите добавить кнопку «назад к альбомам» в отдельных галереях. Такая вещь особенно важна, когда вы начинаете возиться с историей, как если бы пользователь, например, открыл браузер в режиме просмотра галереи, им не удавалось вернуться к альбомам. – numbers1311407

+0

Спасибо за помощь, я попробую, что вы предложили. Как только я выясню pushstate, следующая вещь, которую я планировал сделать, это добавить кнопку назад к альбому. – Su7ech

ответ

0

По существу, вы хотите реорганизовать обработчик кликов вашего альбома в функцию, которую можно вызвать за пределами инициализации, чтобы построить альбомный вид, а затем вызвать эту функцию, когда альбом cli cked, и на popstate (назад/вперед).

Чтобы это произошло, вы должны хранить ссылку на данные JSON, которые вы пытаетесь создать галереи (либо сами данные, либо XHR, которые вы использовали для его получения). Таким образом, мы можем написать функцию showAlbum, которая вместо этого использует индекс или идентификатор, который мы можем использовать для доступа к выбранному альбому в данных.

Так что-то вроде этого:

// As you're doing your initialization, process the JSON array of albums 
// into a hash by ID (this is one of many ways to go about this, a more 
// robust solution would be to use the XHR promise to ensure the JSON is 
// always there when you need it). 
var albumData = {}; 

function initialize() { 
    $.getJSON('/assets/js/images.json', function(json) { 
    $.each(json.albums, function(i, item) { 
     var photos = item.photos, 
      name = item.name, 
      id  = item.id; 

     // Same as you have now, but with this line: 
     albumData[id] = item; 

     showAlbums(photos, name, id); 
    }); 
    }); 
} 


// Then we create a function to show an album by ID, essentially the same as 
// your click handler now, but retrieving the data from the structure we 
// built out of the JSON. 
function showAlbumById (id) { 
    e.preventDefault(); 
    var album = albumData[id] 
    , photos = album.photos 
    , name = album.name; 
    albums.hide(); 
    gallery.empty().show(); 
    document.title = "Schultz | " + n; 
    $.each(photos, function(i, item) { 
    showGallery(item.href, name); 
    }); 
}); 

Тогда вы замените свой альбом обработчик щелчка вместо этого нажать состояние и вызвать эту функцию. Здесь я использую переменную запроса для представления состояния в URL-адресе и theAlbumId для ясности (в коде, на который ссылается i). Если вы добавите кнопку «назад к альбомам», вы сделаете аналогичный обработчик, но нажмете URL без запроса var.

album.on('click', 'a', function(e) { 
    e.preventDefault(); 
    history.pushState({}, '', '?id='+theAlbumID); 
    showAlbumById(theAlbumId); 
}); 

Это должно обрабатывать часть вещей PushState, но полезная часть вещей требует больше работы. Нам нужно иметь возможность идти как назад, так и вперед между обоими государствами: показывать один альбом или показывать индекс альбома. Для этого вам нужно добавить обработчик для события popstate.

// define `onpopstate` or add a listener for `popstate` on the window 
window.onpopstate = function (state) { 
    // pseudocode, you'd need to write or find a function to pull query vars 
    var albumId = getQueryParameter('id'); 

    // if an album ID is in the query string, show it 
    if (albumId) { 
    showAlbumById(albumId); 
    } 
    // otherwise show the index (this should probably be another function) 
    else { 
    albums.show(); 
    gallery.empty().hide(); 
    document.title = "Schultz"; 
    } 
}; 

Затем, наконец, для обработки пользователей обновить страницу или посетив альбом URL напрямую, вы хотели бы также проверить строку запроса для альбома ID на странице загрузки и показать альбом так же, как в popstate (popstate в некоторых браузерах работает на загрузке страницы, но это не должно быть)

+0

Большое вам спасибо за ваш ответ. У меня просто пара вопросов. Во-первых, как вы передаете json-данные функции showAlbumById, используя приведенное выше? И это функции, которые будут использоваться для отображения галереи данного альбома? Также происходит ли событие click вне функции или внутри функции showAlbumsById? – Su7ech

+0

1. Вам не нужно передавать данные функции, потому что они сохраняются после получения из JSON. Таким образом, вы просто сделаете переменную 'albumData' доступной для функции showAlbumByID, объявив ее в той же области или выше. То, как код написан 'showAlbumByID', никогда не будет вызван до тех пор, пока запрос JSON не вернется, поэтому вы бы знали, что он всегда был там. – numbers1311407

+0

2. Да, будет отображаться 'showAlbumByID', чтобы отобразить отдельную галерею, и вы бы назвали ее нажатием на альбом, в браузере назад/вперед в галерею и в конце инициализации, чтобы загрузить текущую галерею (если, например, вы сразу посетили «/mypage.html?id=1» или обновили страницу). – numbers1311407

Смежные вопросы