在前端开发中,我们经常会遇到需要控制函数执行时机的场景,比如仅在页面刷新或者从外部链接进入页面时运行特定逻辑,而在页面内部路由跳转时不触发。要实现这个需求,需要结合页面加载机制和导航类型判断来完成。

核心实现思路
首先需要区分不同的页面访问场景:页面刷新会触发浏览器的重新加载流程,从外部链接进入属于全新的页面访问,这两种场景都会触发window.onload或者DOMContentLoaded事件;而单页应用(SPA)的内部路由跳转不会重新加载整个页面,只会更新路由状态,因此不会触发完整的页面加载事件。
判断页面刷新场景
浏览器提供了performance.getEntriesByType('navigation')接口,可以获取当前页面的导航类型,其中type字段为reload时表示页面是刷新触发的。
// 判断是否为页面刷新
function isPageReload() {
const navigationEntries = performance.getEntriesByType('navigation');
if (navigationEntries.length > 0) {
return navigationEntries[0].type === 'reload';
}
// 兼容旧浏览器,通过检查performance.navigation(已废弃但仍可用)
if (performance.navigation) {
return performance.navigation.type === performance.navigation.TYPE_RELOAD;
}
return false;
}
判断是否为外部链接进入
外部链接进入的页面属于首次访问,此时document.referrer为空,或者来源域名和当前页面域名不一致,同时结合导航类型为navigate(正常导航)来判断。
// 判断是否为外部链接进入
function isFromExternalLink() {
const navigationEntries = performance.getEntriesByType('navigation');
let navigationType = 'navigate';
if (navigationEntries.length > 0) {
navigationType = navigationEntries[0].type;
} else if (performance.navigation) {
// 旧浏览器兼容
navigationType = performance.navigation.type === performance.navigation.TYPE_NAVIGATE ? 'navigate' : '';
}
// 导航类型为正常导航,且来源为空或者来源域名和当前域名不同
if (navigationType === 'navigate') {
const referrer = document.referrer;
if (!referrer) {
return true;
}
const currentDomain = window.location.hostname;
try {
const referrerDomain = new URL(referrer).hostname;
return referrerDomain !== currentDomain;
} catch (e) {
return false;
}
}
return false;
}
完整实现示例
结合上述两个判断函数,我们可以实现仅在页面刷新或外部链接进入时运行目标函数。
// 目标执行函数
function targetFunction() {
console.log('仅在页面刷新或外部链接进入时执行');
// 这里写你的业务逻辑
}
// 页面加载完成后判断执行
window.addEventListener('DOMContentLoaded', function() {
const isReload = isPageReload();
const isExternal = isFromExternalLink();
if (isReload || isExternal) {
targetFunction();
}
});
单页应用适配方案
如果是单页应用,内部路由跳转不会触发DOMContentLoaded事件,此时需要监听路由变化,同时判断是否为首次进入路由。
// 假设使用Vue Router
import { onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
export default {
setup() {
const router = useRouter();
let isFirstEnter = true;
const handleRouteChange = (to, from) => {
// from为空表示首次进入路由,即外部链接进入或者刷新
if (!from && (isPageReload() || isFromExternalLink())) {
targetFunction();
}
isFirstEnter = false;
};
onMounted(() => {
// 初始进入时判断
if (isPageReload() || isFromExternalLink()) {
targetFunction();
}
// 监听路由变化
router.afterEach(handleRouteChange);
});
onUnmounted(() => {
router.afterEach(handleRouteChange);
});
}
};
注意事项
performance.getEntriesByType('navigation')在IE浏览器中不支持,需要做好兼容处理。document.referrer在某些情况下可能被浏览器策略限制,导致获取为空,需要结合业务场景调整判断逻辑。- 单页应用的路由监听需要根据使用的路由库(如React Router、Vue Router)调整对应的监听方式。
JavaScript页面刷新外部链接函数执行页面加载修改时间:2026-07-09 22:39:34