这个需求大概是这样子:
我做的一个聊天Demo,在搜索框搜索用户,可以滚动到指定的用户。然后成选中状态。
这是目前状态,我搜索南宫仆射 ,想要下面的用户列表直接滚动到南宫仆射并改变CSS样式。
查询之后是这个子:
嗯,我的思路:
在搜索框搜索到用户之后会返回一个用户对象,之后会调用列表的点击事件,改变CSS样式及做一些聊天的逻辑。然后需要获取到列表对应的id值,直接使用 document.getElementById(it).scrollIntoView();
具体实现:
列表:使用vue的v-for指令 ,这里的id值使用的是遍历的索引值,外层是一个自定义滚动条组件。样式也是使用vue指令,一个语法糖。
<GeminiScrollbar class="my-scroll-bars"> <li v-for="(item,index) in hrs" :id="index" :key="index" :class="{ active: currentSession?item.username === currentSession.username:false}" @click="changeCurrentSession(item)"> <img class="avatar" :src="item.userface"> <el-badge :is-dot="isDot[user.username+'#'+item.username]"> <p class="name">{{item.name}}</p> </el-badge> </li> </GeminiScrollbar>
搜索框:这里使用带提示的输入框,
<el-autocomplete v-model="SearchHr" class="input-with-select" popper-append-to-body="false" style="width: 90%;padding-left: 5%;padding-top: 10px;margin-bottom: 10px" size="small" :fetch-suggestions="querySearch" placeholder="请输入内容" @select="handleSelect" > <el-button slot="append" icon="el-icon-search" @click="SearchCurrentSession(SearchHr)"></el-button> </el-autocomplete>
JS代码:请求为get请求的axios封装,hr为查询返回的对象,hrs为所有的列表对象。
SearchCurrentSession() { this.getRequest("/chat/?name=" + this.SearchHr).then(resp => { if (resp) { this.hr = resp; this.SearchHr = ''; this.changeCurrentSession(this.hr); let it = 0; this.hrs.forEach((item, index) => { if (item.name == this.hr.name) { it = index; } }) document.getElementById(it).scrollIntoView(); // document.getElementsByClassName("active")[0].scrollIntoView(); } });
changeCurrentSession(currentSession) { this.$store.commit('changeCurrentSession', currentSession) },
页面全部代码:
<template> <div style="display: flex;justify-content:space-between;height: 100%;width: 100%"> <div class="leftlist"> <el-menu background-color="#2e3238" router class="el-menu-vertical-demo" active-text-color="#67C23A" text-color="#fff" :collapse="isCollapse"> <el-menu-item index="/chat" style="padding-left: 10px;margin:10px 0px 20px 2px"> <el-tooltip effect="light" placement="right-start" popper-class="el-scrollbar"> <div slot="content"> <div style="margin-top: 5px;font-size: 13px;lineHeight:1.5;"> <div>用户名:{{user.name}}</div> <div>手机号码:{{user.phone}}</div> <div>电话号码:{{user.telephone}}</div> <div>地 址:{{user.address}}</div> <div>备注:{{user.remark}}</div> </div> </div> <img class="avatar" :src="user.userface" :alt="user.name"></el-tooltip> </el-menu-item> <el-menu-item index="/chat" style="padding-left: 15px"> <i class="fa fa-weixin fa-2x"></i> </el-menu-item> <el-menu-item index="/chat" style="padding-left: 15px"> <i class="fa fa-windows fa-2x"></i> </el-menu-item> <el-menu-item index="/chat" style="padding-left: 15px"> <i class="fa fa-modx fa-2x"></i> </el-menu-item> <el-menu-item index="/chat" style="padding-left: 15px"> <i class="fa fa-share-alt fa-2x"></i> </el-menu-item> </el-menu> </div> <div id="list"> <div style="height:100%;width:100%;overflow-x: hidden"> <ul style="padding-left: 0px; overflow-x: hidden;"> <el-autocomplete v-model="SearchHr" class="input-with-select" popper-append-to-body="false" style="width: 90%;padding-left: 5%;padding-top: 10px;margin-bottom: 10px" size="small" :fetch-suggestions="querySearch" placeholder="请输入内容" @select="handleSelect" > <el-button slot="append" icon="el-icon-search" @click="SearchCurrentSession(SearchHr)"></el-button> </el-autocomplete> <GeminiScrollbar class="my-scroll-bars"> <li v-for="(item,index) in hrs" :id="index" :key="index" :class="{ active: currentSession?item.username === currentSession.username:false}" @click="changeCurrentSession(item)"> <img class="avatar" :src="item.userface"> <el-badge :is-dot="isDot[user.username+'#'+item.username]"> <p class="name">{{item.name}}</p> </el-badge> </li> </GeminiScrollbar> </ul> </div> </div> </div> </template> <script> import {mapState} from 'vuex' export default { name: 'list', data() { return { isCollapse: true, SearchHr: '', hr: "", restaurants: [], user: JSON.parse(window.sessionStorage.getItem("user")) } }, computed: { ...mapState([ 'hrs', 'isDot', 'currentSession' ]) }, methods: { SearchCurrentSession() { this.getRequest("/chat/?name=" + this.SearchHr).then(resp => { if (resp) { this.hr = resp; this.SearchHr = ''; this.changeCurrentSession(this.hr); let it = 0; this.hrs.forEach((item, index) => { if (item.name == this.hr.name) { it = index; } }) document.getElementById(it).scrollIntoView(); // document.getElementsByClassName("active")[0].scrollIntoView(); } }); }, querySearch(queryString, cb) { this.restaurants = this.loadAll(); let restaurants = []; this.restaurants.forEach(value => { let {name, username} = value; let restaurant = {value: name, username: username} restaurants.push(restaurant); }); var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants; // 调用 callback 返回建议列表的数据 cb(results); }, createFilter(queryString) { return (SearchHr) => { return (SearchHr.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0); }; }, loadAll() { return this.hrs; }, changeCurrentSession(currentSession) { this.$store.commit('changeCurrentSession', currentSession) }, handleSelect(item) { console.log(item); } }, mounted() { this.$store.dispatch('initData'); } } </script> <style lang="scss" scoped> .my-scroll-bars { height: 610px; } /* override gemini-scrollbar default styles */ /* vertical scrollbar track */ .gm-scrollbar.-vertical { background-color: #f0f0f0 } /* horizontal scrollbar track */ .gm-scrollbar.-horizontal { background-color: transparent; } /* scrollbar thumb */ .gm-scrollbar .thumb { background-color: rebeccapurple; } .gm-scroll-view { overflow-x: hidden; } .gm-scrollbar .thumb:hover { background-color: fuchsia; } input-with-select { margin-top: 50px; padding-top: 20px; } .el-scrollbar__wrap { width: 100%; height: 100%; overflow-x: hidden; } .el-menu-item is-active { padding-left: 10px; } .el-menu-vertical-demo { background-color: #2e3238; width: 80px; height: 100%; /*opacity:0.8;*/ } .leftlist { background-color: transparent; width: 90px; height: 700px; overflow-x: hidden; } .avatar { width: 45px; height: 45px; /*这个是图片和文字居中对齐*/ border-radius: 5px; margin-top: 5px; } .el-scrollbar__wrap { background-color: #E4E7ED; } #el-scrollbar { background-color: #E4E7ED; } #list { background-color: #E4E7ED; width: 100%; overflow-x: hidden; li { padding: 7px 15px; border-bottom: 1px solid #E4E7ED; cursor: pointer; list-style: none; color: #505458; &:hover { background-color: rgba(0, 0, 0, 0.07); } } li.active { /*注意这个是.不是冒号:*/ background-color: rgba(0, 0, 0, 0.1); } .avatar { border-radius: 2px; width: 30px; height: 30px; vertical-align: middle; } .name { display: inline-block; margin-left: 15px; margin-top: 0px; margin-bottom: 0px; } } </style>
总结
到此这篇关于Vue列表实现滚动到指定位置样式改变的文章就介绍到这了,更多相关Vue列表实现滚动到指定位置样式改变内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
如何控制滚动条滚动到指定位置后,整体固定,滚动条控制某一元素移动,元素移动完成后整体才可以继续往下滑,求求大佬们指点!!!o(╥﹏╥)o
求问,有没有懂页面到一定位置透明度渐显div的全代码 只能做出一半,就是到一定位置div渐显,但是并不会改JS动画,div是先存在再从0-100透明
本文向大家介绍jQuery实现滚动条滚动到子元素位置(方便定位),包括了jQuery实现滚动条滚动到子元素位置(方便定位)的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: jQuery: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!
本文向大家介绍vue实现数字滚动效果,包括了vue实现数字滚动效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了vue实现数字滚动的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍vue实现列表滚动的过渡动画,包括了vue实现列表滚动的过渡动画的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Vue实现列表滚动过渡动画的具体代码,供大家参考,具体内容如下 效果图 失帧比较严重,在手机上效果更佳。 原理分析 这个滚动页面由两个部分布局(底部固定的Tab页面除外)。一个是顶部的banner轮播,一个是下面的列表。这里的重点是做列表的动画,banner轮
本文向大家介绍js实现滚动条滚动到某个位置便自动定位某个tr,包括了js实现滚动条滚动到某个位置便自动定位某个tr的使用技巧和注意事项,需要的朋友参考一下 要实现带滚动条的table,定位到某个tr,其实是很简单的,只有几行js代码就可以完成,具体内容如下 js代码 html 效果图: 虽说是几行代码,但要彻底弄懂。要熟悉animate的使用,scrollTop,.offsetTop的意思方可得心