点击导航项跳转到指定map,由于导航是flexd浮动元素,回遮挡部分map,所以锚点不能用。
步骤
通过选择器获取多个a标签
2.遍历a标签
由于a标签跳转的地址不是我们想要的效果,组织默认动作
监听用户点击的变量a元素
5.获取我们需要的href -- 是字符串
通过字符串为选择器来获取相应的div(map)
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault //阻止a标签默认动作
let a = x.currentTarget // 监听用户点击的变量a元素
a.getAttribute('href') // 获取对应的map(href)
a.href //这样获取的href是浏览器解析过的,需要a.getAttribute来获取用户自己写的没被处理的href
}
}
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault //阻止a标签默认动作
let a = x.currentTarget // 监听用户点击的变量a元素
let href = a.getAttribute('href') // 获取对应的map(href),href此时是字符串
let element = document.querySelector(href) //以字符串'href'为选择器获取href元素,元素变量名element
console.log(element) //点击相应的导航项,会打印出相应的div(map)
}
}
获取固定的map距离页面顶部的top值,这个值不会随着滚动变化
上边四句可以一句话写完
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault
let a = x.currentTarget
let href = a.getAttribute('href')
let element = document.querySelector(href)
let top = element.offsetTop //获取map距离页面的top的值,不会随着滚动改变。这样好处就是我们可以修改它的值
window.scrollTo(0. top - 80) // 用户滑到 x:0 y:top-80(修改可以到达我们想要的距离)
}
}
缓动动画效果
由于是操控滚动条,css实现不了,必须用js来实现
js动画小案例
1秒之后开始动
距离100px内持续动
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault
let a = x.currentTarget
let href = a.getAttribute('href')
let element = document.querySelector(href)
let top = element.offsetTop
let n = 25 //一共动25次
let duration = 500 / n // 多久动一次
let currentTop = window.scrollY //当前top值,用户点击前取的top值,也可以理解为点击瞬间取的
let targetTop = top - 80 //目标top值
let distance = (targetTop - currentTop) / n //每次移动多少距离
let i = 0 //第几次
srtInterval(() =>{
if(i === n){
window.clearInterval(id)
return
}
i = i + 1 //每次移动i+1
window.scrollTo(0.currentTop + distance * i)
},duration)
}
深度截图_选择区域_20180310181344.png
调用tween.js库
上述虽然实现了缓动动画要过,但是过度不够流畅,没达到想要的效果,这时可以调用tweeb.js库
//tween.js用法
var box = document.createElement('div');
box.style.setProperty('background-color', '#008800');
box.style.setProperty('width', '100px');
box.style.setProperty('height', '100px');
document.body.appendChild(box);
// Setup the animation loop.
function animate(time) {
requestAnimationFrame(animate);
TWEEN.update(time);
}
requestAnimationFrame(animate);
var coords = { x: 0, y: 0 }; // Start at (0, 0)
var tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'.
.to({ x: 300, y: 200 }, 1000) // Move to (300, 200) in 1 second.
.easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
.onUpdate(function() { // Called after tween.js updates 'coords'.
// Move 'box' to the position described by 'coords' with a CSS translation.
box.style.setProperty('transform', 'translate(' + coords.x + 'px, ' + coords.y + 'px)');
})
.start(); // Start the tween immediately.
首先需要js引入,因为他给的是相对路径,我们不能用,所以需要搜索,CDN JS,输入tween.js,复制引入地址。
深度截图_选择区域_20180310184406.png
接下来尝试修改官方给的代码
深度截图_选择区域_20180310185403.png
tween.js库实现缓动动画。
//初始代码
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault
let a = x.currentTarget
let href = a.getAttribute('href')
let element = document.querySelector(href)
let top = element.offsetTop
let currentTop = window.scrollY //当前距离页面的top值
let targetTop = top - 80 //目标top值
function animate(time) {
requestAnimationFrame(animate);
TWEEN.update(time);
}
requestAnimationFrame(animate);
var coords = {y: currentTop}; //Y初始值
var tween = new TWEEN.Tween(coords)
.to({y: targetTop}, 1000) //一秒Y移动到目标值
.easing(TWEEN.Easing.Quadratic.IntOut) // 加速再减速动画方式
// onUpdate函数每次都会调用coords,每次都会被tween改变它的值,每次调用y就不是currentTop了。
.onUpdate(function() {
window.scrollTo(coords.y)
})
.start();
}
这样做动画流畅了,但是每次都是1秒,因为每个map高度都不同,所以有的看着加载很慢,我们需要修改下代码,比如100px用一秒。200px就用两秒。你是100px的几倍就用几秒。我们设置距离s = targetTop - currentTop; .to({y: targetTop}, (s/100) * 500) //Y移动到目标值,用多少长时间,时间是根据s成倍增长的,假如距离很长,我们设置时间t = (s/100*300); if(t > 500){ t = 500},这样不管页面距离多长,都要在500毫秒之内完成。这样做有个BUG,当点击回滚的时候,目标距离变成负数了,但是时间不能是负数,时间就需要求个绝对值(var t =Math.abs( (s/100)*300)),不管正负都是正值。
let aTags = document.querySelectoeAll(.nav > ul > li > a) //获取多个a标签
for( let i = 0; i < aTags.length; i++){
aTags[i].onclick = function(x){
x.preveentDefault
let a = x.currentTarget
let href = a.getAttribute('href')
let element = document.querySelector(href)
let top = element.offsetTop
let currentTop = window.scrollY //当前距离页面的top值
let targetTop = top - 80 //目标top值
let s = targetTop - currentTop //设置目标总路程
var t = (s/100)*300 //目标是100px的几倍,时间就是300毫秒的多少倍
if(t>500){ t = 500} //假如页面距离过长,时间t大于500毫秒就让完成动作时间等于500毫秒
var tween = new TWEEN.Tween(coords)
to({y: targetTop}, t) //一秒Y移动到目标值
.easing(TWEEN.Easing.Quadratic.IntOut) // 加速再减速动画方式
// onUpdate函数每次都会调用coords,每次都会被tween改变它的值,每次调用y就不是currentTop了。
.onUpdate(function() {
window.scrollTo(0,coords.y)
})
.start();
}
//时间求绝对值
var t =Math.abs( (s/100)*300) //目标是100px的几倍,时间就是300毫秒的多少倍