IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 微信小程序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);
    }
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:34:50  更:2021-09-23 11:35:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:15:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码