将 pushState() 和 popstate 添加到我的项目中
Adding pushState() and popstate to my project
我有一个正在处理的项目,它有一个画廊。图库的工作方式是用户看到一个图像列表,每个图像都是一个 "album",链接到给定画廊的更多图像。我目前可以正常工作,但是当用户在转到所选画廊后单击后退按钮时,他们不会返回到相册列表。例如,如果您是主页,请单击相册页面,然后打开一个图库。单击后退按钮后,您将返回主页。
所以我想解决这个问题,我可以使用历史记录 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);
}
}));
感谢任何帮助,谢谢
本质上,您要做的是将您的相册点击处理程序重构为一个函数,该函数可以在初始化 外部 调用以构建相册视图,然后在以下情况下调用该函数单击相册,然后 popstate
(back/forward).
要做到这一点,您应该存储对您为构建画廊而提取的 JSON 数据的引用(数据本身或您用来检索它的 XHR)。这样我们就可以编写一个 "showAlbum" 函数来获取索引或 ID,我们可以使用它来访问数据中选定的专辑。
所以像这样:
// 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
引用)。如果你添加一个 "back to albums" 按钮,你会做一个类似的处理程序但是按下 URL
没有查询 var.
album.on('click', 'a', function(e) {
e.preventDefault();
history.pushState({}, '', '?id='+theAlbumID);
showAlbumById(theAlbumId);
});
这应该可以处理 pushState 部分,但 popstate 部分需要更多工作。我们需要能够在两种状态之间来回移动:显示单个专辑或显示专辑索引。为此,您需要为 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 在某些浏览器中有 运行 页面加载,但它不应该)
我有一个正在处理的项目,它有一个画廊。图库的工作方式是用户看到一个图像列表,每个图像都是一个 "album",链接到给定画廊的更多图像。我目前可以正常工作,但是当用户在转到所选画廊后单击后退按钮时,他们不会返回到相册列表。例如,如果您是主页,请单击相册页面,然后打开一个图库。单击后退按钮后,您将返回主页。
所以我想解决这个问题,我可以使用历史记录 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);
}
}));
感谢任何帮助,谢谢
本质上,您要做的是将您的相册点击处理程序重构为一个函数,该函数可以在初始化 外部 调用以构建相册视图,然后在以下情况下调用该函数单击相册,然后 popstate
(back/forward).
要做到这一点,您应该存储对您为构建画廊而提取的 JSON 数据的引用(数据本身或您用来检索它的 XHR)。这样我们就可以编写一个 "showAlbum" 函数来获取索引或 ID,我们可以使用它来访问数据中选定的专辑。
所以像这样:
// 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
引用)。如果你添加一个 "back to albums" 按钮,你会做一个类似的处理程序但是按下 URL
没有查询 var.
album.on('click', 'a', function(e) {
e.preventDefault();
history.pushState({}, '', '?id='+theAlbumID);
showAlbumById(theAlbumId);
});
这应该可以处理 pushState 部分,但 popstate 部分需要更多工作。我们需要能够在两种状态之间来回移动:显示单个专辑或显示专辑索引。为此,您需要为 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 在某些浏览器中有 运行 页面加载,但它不应该)