怎样用JavaScript处理路由?

来源:IPIPP.com作者:头衔:全栈工程师
导读:本期聚焦于小伙伴创作的《怎样用JavaScript处理路由?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《怎样用JavaScript处理路由?》有用,将其分享出去将是对创作者最好的鼓励。

在前端单页应用开发中,路由是实现无刷新页面切换的核心能力,很多开发者会问怎样用JavaScript处理路由。其实JavaScript处理路由不需要依赖第三方库,原生就能实现两种主流方案,分别是hash路由和history路由,下面我们逐一讲解。

怎样用JavaScript处理路由?

一、hash路由的实现

hash路由依赖URL中的#后面的hash值变化来触发路由切换,它的优势是兼容性好,所有浏览器都支持,而且hash变化不会触发页面刷新,也不需要服务器做额外配置。

实现原理

我们可以通过监听hashchange事件来捕获hash值的变化,然后根据不同的hash值匹配对应的页面组件进行渲染。

代码示例

// 定义路由映射表,key是hash值,value是对应的渲染函数
const routes = {
  '/': function() {
    document.getElementById('app').innerHTML = '<h1>首页</h1><p>这是首页内容</p>';
  },
  '/about': function() {
    document.getElementById('app').innerHTML = '<h1>关于我们</h1><p>这是关于页面内容</p>';
  },
  '/contact': function() {
    document.getElementById('app').innerHTML = '<h1>联系我们</h1><p>这是联系页面内容</p>';
  }
};

// 路由渲染函数,根据当前hash匹配对应路由
function renderRoute() {
  // 获取当前hash,去掉开头的#
  const hash = window.location.hash.slice(1) || '/';
  // 如果路由不存在,渲染404页面
  if (routes[hash]) {
    routes[hash]();
  } else {
    document.getElementById('app').innerHTML = '<h1>404</h1><p>页面不存在</p>';
  }
}

// 监听hash变化事件
window.addEventListener('hashchange', renderRoute);
// 页面加载时先执行一次渲染
window.addEventListener('load', renderRoute);

二、history路由的实现

history路由基于HTML5提供的history API实现,常用的API有pushStatereplaceStatepopstate事件,它的URL没有#,看起来更美观,但是需要服务器配合处理页面刷新的问题。

实现原理

我们使用pushState方法修改浏览器的历史记录,同时监听popstate事件来捕获浏览器前进后退操作,再根据当前的路径匹配对应的路由进行渲染。

代码示例

// 定义路由映射表,key是路径,value是对应的渲染函数
const routes = {
  '/': function() {
    document.getElementById('app').innerHTML = '<h1>首页</h1><p>这是首页内容</p>';
  },
  '/about': function() {
    document.getElementById('app').innerHTML = '<h1>关于我们</h1><p>这是关于页面内容</p>';
  },
  '/contact': function() {
    document.getElementById('app').innerHTML = '<h1>联系我们</h1><p>这是联系页面内容</p>';
  }
};

// 路由渲染函数,根据当前路径匹配对应路由
function renderRoute() {
  const path = window.location.pathname || '/';
  if (routes[path]) {
    routes[path]();
  } else {
    document.getElementById('app').innerHTML = '<h1>404</h1><p>页面不存在</p>';
  }
}

// 封装路由跳转函数,使用pushState修改历史记录,不触发页面刷新
function navigateTo(path) {
  window.history.pushState({}, '', path);
  renderRoute();
}

// 监听浏览器前进后退事件
window.addEventListener('popstate', renderRoute);
// 页面加载时先执行一次渲染
window.addEventListener('load', renderRoute);

// 给页面中的链接绑定跳转事件,阻止默认跳转行为
document.querySelectorAll('a[data-link]').forEach(link => {
  link.addEventListener('click', function(e) {
    e.preventDefault();
    const path = this.getAttribute('href');
    navigateTo(path);
  });
});

三、两种路由方案的对比

我们可以根据实际需求选择合适的路由方案,下面是两种方案的对比:

对比项hash路由history路由
URL格式带#,如http://ippipp.com/#/about不带#,如http://ippipp.com/about
兼容性兼容所有浏览器兼容IE10及以上浏览器
服务器配置不需要额外配置需要配置所有路径指向入口文件
监听事件hashchangepopstate

四、路由参数处理

实际开发中经常需要处理带参数的路由,比如/user/123这样的动态路由,我们可以通过正则匹配的方式来提取路由参数。

动态路由匹配示例

// 定义带参数的路由规则,:id是动态参数
const routes = [
  { path: '/', component: function() { document.getElementById('app').innerHTML = '<h1>首页</h1>'; } },
  { path: '/user/:id', component: function(params) { 
    document.getElementById('app').innerHTML = `<h1>用户页面</h1><p>用户ID是:${params.id}</p>`; 
  } }
];

// 匹配路由并提取参数
function matchRoute(path) {
  for (let route of routes) {
    // 将路由规则转为正则,比如/user/:id转为^/user/([^/]+)$
    const regex = new RegExp('^' + route.path.replace(/:(\w+)/g, '([^/]+)') + '$');
    const match = path.match(regex);
    if (match) {
      // 提取参数,match[1]及之后的是动态参数
      const paramNames = (route.path.match(/:(\w+)/g) || []).map(name => name.slice(1));
      const params = {};
      paramNames.forEach((name, index) => {
        params[name] = match[index + 1];
      });
      return { component: route.component, params };
    }
  }
  return null;
}

// 渲染路由的函数
function renderRoute() {
  const path = window.location.pathname || '/';
  const matched = matchRoute(path);
  if (matched) {
    matched.component(matched.params);
  } else {
    document.getElementById('app').innerHTML = '<h1>404</h1>';
  }
}

以上就是用JavaScript原生处理路由的完整方法,开发者可以根据项目需求选择合适的方案,也可以基于这些原理封装更符合自己项目的路由工具。

JavaScript路由处理前端路由hash路由history路由修改时间:2026-05-29 23:03:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。