单页面路由
监听url地址的改变
思路: 用hashchange事件 监听url地址中hash值的变化,
只要hash值发生变化hashchange的回调函数就会执行,
在回调函数内部获取最新的hash值 ( location.hash ) ,
使用switch或者if 判断, 根据不同的hash值调用不同的函数, 完成内容的渲染.
<body>
<!-- hash路由方法:在盒子中创建三个a标签 -->
<div class="nav">
<a href="#/home">首页</a>
<a href="#/find">发现</a>
<a href="#/+">+</a>
<a href="#/singlecenter">个人中心</a>
<a href="#/more">更多</a>
</div>
<div class="content">
<!-- 内容区域,当点击页面跳转时,内容将渲染至此区域 -->
</div>
</body>
<script>
// 监听url地址的改变
// 思路: 用hashchange事件 监听url地址中hash值的变化,
// 只要hash值发生变化hashchange的回调函数就会执行,
// 在回调函数内部获取最新的hash值 ( location.hash ) ,
// 使用switch或者if 判断, 根据不同的hash值调用不同的函数, 完成内容的渲染.
window.onhashchange=function(){
if(location.hash=='#/home'){
home_page()
}else if(location.hash=='#/find'){
find_page()
}
}
//渲染内容
function home_page(){
document.querySelector('.content').innerHTML='wukwkwkwkw'
}
function find_page(){
document.querySelector('.content').innerHTML='KWEKWKWKW'
}
</script>
history路由:
思路: 点击不同的按钮, 通过history.pushState()切换不同的路由地址,
然后根据不同的路由地址调用不同的函数 渲染不同的内容.
<body>
<!-- history路由方法:在盒子中创建三个a标签 -->
<!-- 思路: 点击不同的按钮, 通过history.pushState()切换不同的路由地址,
然后根据不同的路由地址调用不同的函数 渲染不同的内容. -->
<div class="nav">
<a href="/home">首页</a>
<a href="/find">发现</a>
<a href="/+">+</a>
<a href="/singlecenter">个人中心</a>
<a href="/more">更多</a>
</div>
<div class="content">
<!-- 内容区域,当点击页面跳转时,内容将渲染至此区域 -->
</div>
</body>
<script>
// 借助 history 对象的 pushState() 方法 添加一个新的历史记录 ( 地址栏的地址会发生改变 )
// 注意: pushState() 必须在非 file:// 协议下调用.
// 语法: history.pushState( 历史记录的状态 , 保留字符串 , url地址 );
// this.href 获取的是 当前点击的a标签的href属性值
//给每个标签添加点击事件
var title=document.querySelectorAll('a')
//进行遍历
title.forEach((item)=>{
//添加点击事件,点击又要阻止a标签原本的跳转页面的属性
item.onclick=function(e){
e.preventDefault();
//使用history.pushState语法
history.pushState({},'',this.href)
if(location.hash=='#/home'){
home_page()
}else if(location.hash=='#/find'){
find_page()
}
}
})
// 渲染
function home_page(){
document.querySelector('.content').innerHTML='武拉拉'
}
function find_page(){
document.querySelector('.content').innerHTML='武拉拉lkalalal'
}
</script>
单页面路由的封装
<body>
<div class="nav">
<button>1</button>
<button>2</button>
<button>3</button>
</div>
<div class="content">
<!-- 渲染区域 -->
</div>
</body>
<script>
//定义个路由表
var routes=[
{path:'/home',component:home_page},
{path:'/find',component:find_page},
{path:'/mine',component:geren_page},
]
//给所有button标签绑定点击事件
//先进行遍历
var title=document.querySelectorAll('button')
title.forEach((item,index)=>{
//绑定点击事件
item.onclick=function(e){
//阻止默认跳转行为
e.preventDefault()
//调用history.pushState()添加一个新的历史记录
history.pushState({},'',routes[index].path)
routes[index].component()
}
})
//渲染内容
function home_page(){
document.querySelector('.content').innerHTML='武拉拉'
}
function find_page(){
document.querySelector('.content').innerHTML='武拉拉lkalalal'
}
function geren_page(){
document.querySelector('.content').innerHTML='lalalalal武拉拉lkalalal'
}
</script>
浏览器端的事件循环机制:
<script>
//程序从上往下执行, 当遇到同步任务, 会直接在执行栈中执行, 当遇到异步任务会先放入到任务队列中等待执行, 执行栈的代码执行完毕后, 在事件循环机制下,每隔一个很短的时间去检查任务队列中是否还有未执行的异步任务, 如果有则取出最先放入任务队列一个异步任务放入执行栈开始执行. 在事件循环机制下, 每个放入任务队列中的任务都会被依次执行.
console.log(1);
//对于定时器,从定时器被创建开始, 会等到定时时间到才会将异步任务放入任务队列, 这个定时器等待时间长, 所以会后放入任务队列
setTimeout(()=>{
console.log(2);
},200)
//对于定时器,从定时器被创建开始, 会等到定时时间到才会将异步任务放入任务队列, 这个定时器等待时间短, 所以会先放入任务队列, 在事件循环机制下, 根据任务队列先进先出的特点, 也会优先取出执行.
setTimeout(()=>{
console.log(4);
},100)
console.log(3);
//最终输出结果为: 1 3 4 2
</script>