我的编程空间,编程开发者的网络收藏夹
学习永远不晚

微信小程序scroll-view实现左右联动

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

微信小程序scroll-view实现左右联动

本文实例为大家分享了微信小程序scroll-view实现左右联动的具体代码,供大家参考,具体内容如下

需求:项目中做了一个选择城市的需求,要求全国所有的省市区都按照中文首字母分类并排序,左侧的城市列表和右侧的字母列表实现双向联动。

第一步:根据腾讯提供的javascript SDK提供的接口,获取所有的省市区,并将省市区按照首字母进行分类排序。


let _this = this;
_this.mapCtx = wx.createMapContext("myMap");
        // 实例化API核心类
        qqmapsdk = new QQMapWX({
            key: MAP_KEY,
        });
 
        // 获取全国的城市列表
        qqmapsdk.getCityList({
            success: function (res) {
                let list = res.result[0].concat(res.result[1], res.result[2]);
                _this.allCity = list;
                _this.cityList = _this.pySegSort(list);
            },
            fail: function (error) {
                console.error(error);
            },
            complete: function (res) {
                console.log(res);
            },
        });
 
        pySegSort(arr) {
            if (!String.prototype.localeCompare) return null;
            let letters = "*ABCDEFGHJKLMNOPQRSTWXYZ".split("");
            let zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split("");
            let segs = [];
            let curr;
            letters.forEach(function (item, i) {
                curr = { letter: item, id: item, data: [] };
                arr.forEach(function (item2) {
                    if (
                        (!zh[i - 1] || zh[i - 1].localeCompare(item2.fullname) <= 0) &&
                        item2.fullname.localeCompare(zh[i]) == -1
                    ) {
                        curr.data.push(item2);
                    }
                });
                if (curr.data.length) {
                    curr.data.sort(function (a, b) {
                        return a.fullname.localeCompare(b.fullname);
                    });
                    segs.push(curr);
                }
            });
            return segs;
        },

第二步: 计算各个首字母组成的列表的高度

在使用query.selectAll('.cityList')时应放入setTimeout中异步获取,不然页面还没加载完,获取不到,尝试使用$nextTick()也是没有获取到的。


// 获取热门城市盒子的高度
 let query = wx.createSelectorQuery().in(this);
        query
            .select(".hot-city")
            .boundingClientRect((data) => {
                this.hotCityHeight = data.height;
            })
            .exec();
 
        
        // 获取各个字母分类的块高度
        setTimeout(() => {
            let query = wx.createSelectorQuery().in(this);
            query
                .selectAll(".cityList")
                .boundingClientRect((data) => {
                    console.log(data, "各个城市分类的高度");
                    this.letterBoxHeight = data;
                    this.heightArr = this.getHeiht();
                })
                .exec();
        }, 1000);  // 使用setTimeout进行异步获取,不然获取不到
 
        // 计算每个区域的高度
        getHeiht() {
            let n = this.hotCityHeight;
            let arr = [];
            this.letterBoxHeight.forEach((item) => {
                n = n + item.height;
 
                arr.push(n);
            });
            return arr;
        },

第三步:实现点击右侧,左侧联动。

点击右侧字母列表时,实现左侧城市列表的滚动到可视区域,这时需要 scroll-into-view="childViewId"


// 点击右侧的字母
letterClick(letter, i) {
            this.letterIndex = i;
            this.currentIndex = i;
            this.childViewId = letter;
            setTimeout(() => {
                this.letterIndex = -1;
            }, 500); // 0.5秒后浮出的首字母圆圈消失
        },

第四步:实现滑动左侧,右侧联动。

当滑动城市列表时,需要判断当前的滚动高度,在哪个字母范围内,在该范围内的字母需高亮。


calculateIndex(arr, scrollHeight) {
   let index = "";
   for (let i = 0; i < arr.length; i++) {
                if (scrollHeight >= this.hotCityHeight && scrollHeight < arr[0]) {
                    index = 0;
                } else if (scrollHeight >= arr[i - 1] && scrollHeight < arr[i]) {
                    index = i;
                }
            }
            return index;
        },
        // 计算滚动距离
        scroll(e) {
            let scrollTop = e.detail.scrollTop;
            let scrollArr = this.heightArr;
            let index = this.calculateIndex(scrollArr, scrollTop);
            this.currentIndex = index;
        },

完成代码如下:


created() {
        let _this = this;
        _this.mapCtx = wx.createMapContext("myMap");
        // 实例化API核心类
        qqmapsdk = new QQMapWX({
            key: MAP_KEY,
        });
 
        // 获取全国的城市列表
        qqmapsdk.getCityList({
            success: function (res) {
                let list = res.result[0].concat(res.result[1], res.result[2]);
                _this.allCity = list;
                _this.cityList = _this.pySegSort(list);
            },
            fail: function (error) {
                console.error(error);
            },
            complete: function (res) {
                console.log(res);
            },
        });
    },
    mounted() {
        // 获取热门城市盒子的高度
        let query = wx.createSelectorQuery().in(this);
        query
            .select(".hot-city")
            .boundingClientRect((data) => {
                this.hotCityHeight = data.height;
            })
            .exec();
 
       
        // 获取各个字母分类的块高度
        setTimeout(() => {
            let query = wx.createSelectorQuery().in(this);
            query
                .selectAll(".cityList")
                .boundingClientRect((data) => {
                    console.log(data, "各个城市分类的高度");
                    this.letterBoxHeight = data;
                    this.heightArr = this.getHeiht();
                })
                .exec();
        }, 1000);
    },
    methods: {
        // 给城市列表根据首字母排序
        pySegSort(arr) {
            if (!String.prototype.localeCompare) return null;
            let letters = "*ABCDEFGHJKLMNOPQRSTWXYZ".split("");
            let zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split("");
            let segs = [];
            let curr;
            letters.forEach(function (item, i) {
                curr = { letter: item, id: item, data: [] };
                arr.forEach(function (item2) {
                    if (
                        (!zh[i - 1] || zh[i - 1].localeCompare(item2.fullname) <= 0) &&
                        item2.fullname.localeCompare(zh[i]) == -1
                    ) {
                        curr.data.push(item2);
                    }
                });
                if (curr.data.length) {
                    curr.data.sort(function (a, b) {
                        return a.fullname.localeCompare(b.fullname);
                    });
                    segs.push(curr);
                }
            });
            return segs;
        },
        // 点击右侧的字母
        letterClick(letter, i) {
            this.letterIndex = i;
            this.currentIndex = i;
            this.childViewId = letter;
            setTimeout(() => {
                this.letterIndex = -1;
            }, 500);
        },
        // 计算每个区域的高度
        getHeiht() {
            let n = this.hotCityHeight;
            let arr = [];
            this.letterBoxHeight.forEach((item) => {
                n = n + item.height;
 
                arr.push(n);
            });
            return arr;
        },
        calculateIndex(arr, scrollHeight) {
            let index = "";
            for (let i = 0; i < arr.length; i++) {
                if (scrollHeight >= this.hotCityHeight && scrollHeight < arr[0]) {
                    index = 0;
                } else if (scrollHeight >= arr[i - 1] && scrollHeight < arr[i]) {
                    index = i;
                }
            }
            return index;
        },
        // 计算滚动距离
        scroll(e) {
            let scrollTop = e.detail.scrollTop;
            let scrollArr = this.heightArr;
            let index = this.calculateIndex(scrollArr, scrollTop);
            this.currentIndex = index;
        },
}

<scroll-view scroll-y style="height: 1400rpx" :scroll-into-view="childViewId"             @scroll="scroll">
            <!-- 热门城市 -->
            <view class="hot-city">
                <p>热门城市</p>
                <ul>
                    <li
                        v-for="(item, idx) in hotCityList"
                        :key="idx"
                        :class="fixedPosition === item ? 'selected' : ''"
                        @click="selectCity(item)"
                    >
                        {{ item }}
                    </li>
                </ul>
            </view>
            <!-- 字母列表 -->
            <view class="letterAz">
                <view
                    v-for="(item, idx) in letterAz"
                    :key="idx"
                    class="letter-item"
                    :class="currentIndex === idx ? 'selected' : ''"
                    @click="letterClick(item, idx)"
                >
                    {{ item }}
                    <view v-show="letterIndex === idx" class="pop-item">{{ item }}</view>
                </view>
            </view>
            <!-- 城市列表 -->
            <view v-for="(item, idx) in cityList" :key="idx" class="cityList">
                <view :id="item.id" class="city-letter">{{ item.letter }}</view>
                <view v-for="ele in item.data" :key="ele.id" class="city-name" @click="selectCity(ele.fullname)">{{
                    ele.fullname
                }}</view>
            </view>
</scroll-view>

// 热门城市
.hot-city {
    padding: 38rpx 32rpx;
    p {
        font-size: 28rpx;
        line-height: 40rpx;
        color: #999999;
        margin-bottom: 32rpx;
    }
    ul {
        display: flex;
        flex-wrap: wrap;
        & li {
            background: rgba(0, 0, 0, 0.04);
            border-radius: 16rpx;
            font-size: 28rpx;
            color: #000000;
            text-align: center;
            margin: 8rpx;
            padding: 16rpx 46rpx;
        }
        & li.selected {
            background: rgba(45, 200, 77, 0.12);
            border: 0.66rpx solid #046a38;
            color: #046a38;
        }
    }
}
// 字母列表
.letterAz {
    position: fixed;
    right: 29rpx;
    top: 380rpx;
    font-size: 20rpx;
    line-height: 28rpx;
    color: rgba(0, 0, 0, 0.55);
    .letter-item {
        position: relative;
        margin-top: 4rpx;
        .pop-item {
            position: absolute;
            right: 165%;
            bottom: -100%;
            width: 96rpx;
            height: 96rpx;
            background: #ffffff;
            border: 0.66rpx solid rgba(0, 0, 0, 0.12);
            box-sizing: border-box;
            box-shadow: 0 10rpx 24rpx rgba(0, 0, 0, 0.08);
            border-radius: 100%;
            text-align: center;
            line-height: 96rpx;
            font-size: 40rpx;
            color: rgba(0, 0, 0, 0.85);
        }
    }
    .letter-item.selected {
        color: #046a38;
    }
}
// 城市列表
.cityList {
    margin-left: 32rpx;
    margin-right: 66rpx;
    margin-top: 20rpx;
    .city-letter {
        font-size: 28rpx;
        line-height: 40rpx;
        color: #999999;
    }
    .city-name {
        font-size: 28rpx;
        line-height: 40rpx;
        color: #000000;
        padding: 32rpx 0;
        border-bottom: 2rpx solid rgba(0, 0, 0, 0.12);
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

微信小程序scroll-view实现左右联动

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

微信小程序scroll-view不能左右滑动怎么解决

本文小编为大家详细介绍“微信小程序scroll-view不能左右滑动怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“微信小程序scroll-view不能左右滑动怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
2023-06-08

微信小程序 scroll-view

微信小程序 scroll-view 用法 微信官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html 微信小程序 scrol
2023-08-22

如何解决微信小程序中scroll-view不能左右滑动的问题

这篇文章将为大家详细讲解有关如何解决微信小程序中scroll-view不能左右滑动的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。问题: 在小程序页面布局的时候用到了scroll-view组件,
2023-06-20

微信小程序scroll-view怎么实现自定义滚动条

本篇内容主要讲解“微信小程序scroll-view怎么实现自定义滚动条”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序scroll-view怎么实现自定义滚动条”吧!html