.net a标签触发事件_Link组件和a标签之间的爱恨情仇

ad5c3b71ea584a96c592339e694c25ad.png

说起路由,那么就先来聊聊上古时期的网页是怎么渲染的吧。服务端工程师在后台把页面都构建好,根据浏览器的请求地址,去匹配相应的页面,输出的都是已经生成好的HTML,点击跳转都会重新刷新出一个新的页面。

为了提升用户体验,单页应用(SPA)应运而生,良好的体验,丝般柔滑的页面切换,让人心旷神怡。既然页面由客户端渲染了,路由也随之而来。现在用React或Vue做个页面,谁不加个Router包呢。那么用的是爽的,大家知道其中的原理吗?

不妨在此先说一说前端控制路由的两种形式:

1、hash

大家常常看到的hash就是浏览器上的a标签作为锚点去使用,点击的时候浏览器地址改变了#/**这种新式,并且页面是不会刷新的。上面说的React和Vue所用的路由包,也有hash的形式去切换路由。浏览器原生的提供了一个监听事件“hashchange”,a标签改变url,浏览器的前进后退,window.location改变地址栏的地址 都会触发“hashchange”监听事件,通过这个事件去获取localtion.hash,继而去匹配相应的组件。代码大致如下

<!DOCTYPE html>
<html>
<head>
  <title>hash路由</title>
</head>
<body>
  <div>
    <ul>
      <li><a href="#/page1">page1</a></li>
      <li><a href="#/page2">page2</a></li>
    </ul>
    <div id="route-view"></div>
  </div>
<script type="text/javascript">
  // 下面为hash的路由实现方式
  // 第一次加载的时候,不会执行hashchange监听事件,默认执行一次
  window.addEventListener('DOMContentLoaded', Load)
  window.addEventListener('hashchange', HashChange)
  var routeView = null
  function Load() {
    routeView = document.getElementById('route-view')
    HashChange()
  }
  function HashChange() {
    switch(location.hash) {
    case '#/page1':
      routeView.innerHTML = 'page1'
      return
    case '#/page2':
      routeView.innerHTML = 'page2'
      return
    default:
      routeView.innerHTML = 'page1'
      return
    }
  }

</script>
</body>
</html>

2、history

通过history去控制路由的话,那就比较麻烦了,因为history提供的“popstate“监听事件监听不到pushState、replaceState、a标签这三种形式的改变,浏览器的前进后退是可以监听到的。有什么好的解决方案呢?遍历页面上的所有a标签,然后阻止它的默认事件,加上点击事件回调函数,在函数内,获取a标签的href属性值,再通过pushState去改变浏览器上的pathname,最后手动执行一次popstate监听的回调函数,匹配相应的路由。代码如下

(⚠️注意,以下代码不能直接打开浏览器访问,因为地址是本地地址,会有问题,需要启动服务打开)

<!DOCTYPE html>
<html>
<head>
  <title>hash路由</title>
</head>
<body>
  <div>
    <ul>
      <li><a href="/page1">page1</a></li>
      <li><a href="/page2">page2</a></li>
    </ul>
    <div id="route-view"></div>
  </div>
<script type="text/javascript">
  // 下面为history的路由实现方式
  window.addEventListener('DOMContentLoaded', Load)
  window.addEventListener('popstate', PopChange)
  var routeView = null
  function Load() {
    routeView = document.getElementById('route-view')
    PopChange()
    var aList = document.querySelectorAll('a[href]')
    aList.forEach(event => event.addEventListener(function(e) {
      e.preventDefault() //阻止a标签的默认事件
      var href = e.getAttribute('href')
      history.pushState(null, '', href)
      PopChange()
    }))
  }
  function PopChange() {
    switch(location.pathname) {
    case '/page1':
      routeView.innerHTML = 'page1'
      return
    case '/page2':
      routeView.innerHTML = 'page2'
      return
    default:
      routeView.innerHTML = 'page1'
      return
    }
  }
</script>
</body>
</html>

那么说了那么多,大家也应该对Link和a标签的区别有所了解了。就是默认情况下用a标签,默认事件是不会被阻止的,所以点击a标签,页面会刷新。而Link内部阻止的a标签的默认事件,转而去获取它的href值去pushState改变pathname,不会引起页面的刷新。以上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值