scrollIntoView()实现通讯录功能-锚点定位

2,216 阅读2分钟

锚点定位算是一个很熟悉的功能了,以前都是使用a标签的href=#XXX来实现,如下:


但是这种方法地址栏会变化,会给人一种误以为页面刷新的错觉,如果需要进行地址栏的操作,还得加一些判断,比较麻烦,所以采用了一种新的方式来进行锚点定位,就是scrollIntoView

以下为使用scrollIntoView实现的通讯录功能的锚点定位

思路:

需要被定位的元素添加id,使用document.getElementById或者querySelector来获得元素,然后点出来scrollIntoView( )方法


粗略效果图:


具体代码

<template>    
    <div class="test clear">        
        <div class="left-letter">            
            <span 
                v-for="(letter,letterIndex) in letterList" 
                :key="letterIndex" 
                @click="toLetters(letter)">{{letter}}
            </span>        
        </div>        
        <ul class="student-container">            
            <li v-for="(student, stIndex) in studentInfo" :key="stIndex">                
                <span :class="{'spell-letter': true, 'selected': student.spell.toUpperCase().slice(0, 1) === selectLetter}" :id="student.spell.toUpperCase().slice(0, 1)" v-if="stIndex===0 || studentInfo[stIndex].spell.toUpperCase().slice(0, 1) !== studentInfo[stIndex - 1].spell.toUpperCase().slice(0, 1)">{{student.spell.toUpperCase().slice(0, 1)}}</span>                
                <div>                    
                    <var>{{student.name}}</var>                    
                    <var>{{student.number}}</var>                
                </div>            
            </li>        
        </ul>    
    </div>
</template>
<script>
    export default {    
        name: 'test',    
        data(){        
            return {            
                studentInfo: [                
                    {                    
                        name: '白芸维',                    
                        spell: 'baiyunwei',                    
                        number: '001'                
                    },                
                    {                    
                        name: '柏楠',                    
                        spell: 'bonan',                    
                        number: '002'                
                    },                
                    {                    
                        name: '陈建熹',                    
                        spell: 'chenjianxi',                    
                        number: '003'                
                    },                
                    {                    
                        name: '陈天佑',                    
                        spell: 'chentianyou',                    
                        number: '004'                
                    },                
                    {                    
                        name: '东西',                    
                        spell: 'dongxi',                    
                        number: '008'                
                    },                
                    {                    
                        name: '桂怡',                    
                        spell: 'guiyi',                    
                        number: '005'                
                    },                
                    {                    
                        name: '黄英',                    
                        spell: 'huangyin',                    
                        number: '009'                
                    },                
                    {                    
                        name: '黄小',                    
                        spell: 'huangxiao',                    
                        number: '0010'                
                    },                
                    {                    
                        name: '黄决赛',                    
                        spell: 'huangjuesai',                    
                        number: '0011'                
                    },                
                    {                    
                        name: '黄英里',                    
                        spell: 'huangyinli',                    
                        number: '0012'                
                    },                
                    {                    
                        name: '雪梨',                    
                        spell: 'xueli',                    
                        number: '0013'                
                    },                
                    {                    
                        name: '杨颖',                    
                        spell: 'yangyin',                    
                        number: '006'                
                    },                
                    {                    
                        name: '曾志伟',                    
                        spell: 'zengzhiwei',                    
                        number: '007'                
                    },            
                ], //学生信息列表            
                letterList: [], //字母列表            
                selectLetter: '', //被选中的字母        
            }    
        },    
        created() {        
            // 初始化字母列表        
            this.studentInfo.forEach((e, index)=>{   
                //过滤字母,重复的不选         
                if (index === 0) {                
                    this.letterList[0] = e.spell.toUpperCase().slice(0, 1)                
                    this.selectLetter = this.letterList[0]            
                } else if (index != 0 && this.studentInfo[index].spell.toUpperCase().slice(0, 1) !== this.studentInfo[index - 1].spell.toUpperCase().slice(0, 1)) {                
                    this.letterList.push(e.spell.toUpperCase().slice(0, 1))            
                }        
            })    
        },    
        methods: {        
            // 点击左侧字母,右侧学生列表滚动到指定位置        
            toLetters(letter) {            
                this.selectLetter = letter            
                let e = document.getElementById(letter)            
                if (e) {                
                    e.scrollIntoView() //滚动到指定位置            
                }        
            }    
        }
    }
</script>
<style lang="less" scoped>    
    .test {        
        width: 1200px;        
        margin: 20px auto 0;        
        .left-letter {            
            position: fixed;            
            top: 228px;            
            left: 78px;            
            width: 20px;            
            border: 1px solid #d8d8d8;            
            background: #f9f9f9;            
            span {                
                display: block;                
                width: 100%;                
                height: 30px;                
                text-align: center;                
                line-height: 30px;                
                cursor: pointer;            
            }            
            span:hover {                
                background: #d0e8ed;                
                color: #0d858e;            
            }        
        }        
        .student-container {            
            position: relative;            
            float: left;            
            width: 200px;            
            margin-left: 100px;            
            // border: 1px solid #d8d8d8;            
            li {                
                padding: 0 10px;                
                    span {                    
                        position: absolute;                    
                        color: #999;                    
                        font-weight: bold;                
                    }                
                    span.selected {                    
                        color: #0d858e;                
                    }                
                    div {                    
                        padding: 10px 10px 0;                    
                        margin-left: 30px;                    
                        border: 1px solid #d8d8d8;                    
                        var {                        
                            display: block;                        
                            margin-bottom: 10px;                    
                        }                
                    }            
            }        
        }    
    }
</style>
scrollIntoView是js的原生方法,所以需要document.getElementById或者querySelector来获得元素,然后才可以点出来scrollIntoView( )方法

scrollIntoView的默认值为true:

element.scrollIntoView() 
= element.scrollIntoView(true) 
= element.scrollIntoView({block:'start',inline:'nearest'})

element.scrollIntoView(false) = element.scrollIntoView({block:'end',inline:'nearest'})
scrollIntoView可选:

behavior定义动画:'auto' | 'instant' | 'smooth'

block定义滚动位置: 'start' | 'center' | 'end' | 'nearest'

inline: 'start' | 'center' | 'end' | 'nearest'


参考:

developer.mozilla.org/zh-CN/docs/…