LOADING...
React 项目中集成 Pjax 失败的经验总结与视觉模拟方案。由于 React 的渲染机制与 Pjax 在脚本加载及 DOM 替换上存在冲突,作者最终决定放弃 Pjax,转而通过拦截 <a> 标签点击事件、延迟跳转以及 CSS 淡出动画来模拟 Pjax 的无刷新视觉效果,并利用 document.referrer 判断来源以优化下一页面的加载遮罩体验。
暑假在开发一个项目(就是此博客),由于项目需要支持 SEO,所以采用了 React 框架,同时为了提升用户体验,采用了 Pjax 技术。然而,在开发过程中,发现 React 与 Pjax 存在一些冲突,导致页面无法正常加载。经过一番研究,最终决定放弃 Pjax,采用传统的页面跳转方式。
不过,我也额外做了些工作,使现在的“直接跳转”在视觉上与 Pjax 相同。
只是,因为失去了 Pjax,所以目前为止最大的问题是音乐播放器...
我们可以看看 Pjax 的必要要求:
解决方案很简单,在页面切换途中动手脚,使前一个页面的退出状态与后一个页面的载入状态相同,视觉上就感觉不到页面有切换
首先我们应该阻拦用户的跳转操作(a 标签):
这样我们就能硬控用户450ms,用来加载我们的淡出动画
如果你担心用户的网络请求也会慢450ms,那么可以用instant.page实现预加载
淡出动画可以非常简单,你只需要找到页面中变动的部分(我这里是div#viewmap),然后用以下方式给他透明化:
这样就做好了淡出,接下来处理下一个页面的淡入
这里直接看最复杂的要求:页面在载入时有loading遮罩
在这种情况下,我们需要判断上一页面是否是本站点,如果是的话我们就直接关闭遮罩
上面的代码使用referrer检查上一页面,返回<Boolean>,然后我们就可以在页面载入时判断了:
最好是就单独整个scirpt标签,放在遮罩元素的下面
为此我精简了上面的所有代码,并且检查了window是否存在,防止出现Nextjs中的Server与Client不分的错误
目前,音乐播放器还在开发中,暂时无法使用。
document.addEventListener("click", function (event) {
var target = event.target;
if (target.tagName === "A") {
event.preventDefault();
var url = target.href;
// 这里放你的淡出操作
// fadeOutPage("#viewmap")
setTimeout(() => (window.location.href = url), 450);
}
});function fadeOutPage(selector, time = 450) {
const element = document.querySelector(selector);
element.style.opacity = '1';
element.style.transition = `opacity ${time}ms,left ${time}ms`;
element.style.opacity = '0';
}function isReferrerFromMySite() {
const referrer = document.referrer;
const myDomain = window.location.origin;
if (referrer) {
var referrerUrl = new URL(referrer);
return referrerUrl.origin === myDomain;
} else {
return false;
}
}if (isReferrerFromMySite()) {
document.getElementById("loading").style.display = "none";
}
评论