WeChatアプレットのスクロールビューが左右の連動を実現

WeChatアプレットのスクロールビューが左右の連動を実現

この記事では、WeChatアプレットのスクロールビューの左右連動を実現するための具体的なコードを参考までに紹介します。具体的な内容は次のとおりです。

要件:プロジェクトには都市を選択するための要件が​​あり、国内のすべての省、市、地区を中国語のアルファベットの最初の文字に従って分類および並べ替え、左側の都市リストと右側の文字リストが双方向にリンクされている必要があります。

ステップ 1 : Tencent が提供する JavaScript SDK のインターフェイスに従って、すべての省、市、地区を取得し、最初の文字で並べ替えます。

_this = this とします。
_this.mapCtx = wx.createMapContext("myMap");
        // APIコアクラスをインスタンス化します qqmapsdk = new QQMapWX({
            キー: MAP_KEY、
        });
 
        // 全国の都市リストを取得する qqmapsdk.getCityList({
            成功: 関数 (res) {
                リストをres.result[0].concat(res.result[1], res.result[2])とします。
                _this.allCity = リスト;
                _this.cityList = _this.pySegSort(リスト);
            },
            失敗: 関数 (エラー) {
                コンソールエラー(エラー);
            },
            完了: 関数 (res) {
                コンソールログ(res);
            },
        });
 
        pySegSort(arr) {
            if (!String.prototype.localeCompare) が null を返す;
            文字を "*ABCDEFGHJKLMNOPQRSTWXYZ" とします。split("");
            let zh = "これは非常にシンプルでエレガントな文です。ここに書き留めておきます。私は...
            セグメントを [] とします。
            電流を流す;
            文字.forEach(関数(項目, i) {
                curr = { 文字: アイテム、 ID: アイテム、 データ: [] };
                arr.forEach(関数 (item2) {
                    もし (
                        (!zh[i - 1] || zh[i - 1].localeCompare(item2.fullname) <= 0) &&
                        項目2.fullname.localeCompare(zh[i]) == -1
                    ){
                        curr.data.push(item2);
                    }
                });
                (通貨データの長さ)の場合{
                    curr.data.sort(関数(a, b) {
                        a.fullname.localeCompare(b.fullname) を返します。
                    });
                    segs.push(curr);
                }
            });
            セグメントを返します。
        },

ステップ2:各頭文字からなるリストの高さを計算する

query.selectAll('.cityList') を使用する場合は、非同期取得のために setTimeout に入れる必要があります。そうしないと、ページがまだ読み込まれていないため、取得できません。$nextTick() を使用しても取得できません。

// 人気の都市ボックスの高さを取得します。let query = wx.createSelectorQuery().in(this);
        クエリ
            .select(".hot-city")
            .boundingClientRect((データ) => {
                高さ = データ。
            })
            .exec();
 
        
        // 各文字カテゴリのブロックの高さを取得します setTimeout(() => {
            クエリを wx.createSelectorQuery().in(this); にします。
            クエリ
                .selectAll(".cityList")
                .boundingClientRect((データ) => {
                    console.log(data, "各都市の分類の高さ");
                    this.letterBoxHeight = データ;
                    this.heightArr = this.getHeight();
                })
                .exec();
        }, 1000); // 非同期取得にはsetTimeoutを使用します。そうしないと取得できません // 各エリアの高さを計算します getHeiht() {
            n = this.hotCityHeight とします。
            arr = [] とします。
            this.letterBoxHeight.forEach((item) => {
                n = n + アイテムの高さ;
 
                arr.push(n);
            });
            arr を返します。
        },

ステップ 3:右側をクリックして、左側のリンクを実現します。

右側の文字リストをクリックすると、左側の都市リストが表示領域までスクロールします。この場合、scroll-into-view="childViewId" が必要です。

// 右側の文字をクリックします letterClick(letter, i) {
            this.letterIndex = i;
            this.currentIndex = i;
            this.childViewId = 文字;
            タイムアウトを設定する(() => {
                this.letterIndex = -1;
            }, 500); // 最初の円は0.5秒後に消えます},

ステップ 4:左側をスライドして右側をリンクします。

都市リストをスライドするときは、現在のスクロールの高さと、文字を強調表示する必要がある文字範囲を決定する必要があります。

インデックスを計算します(arr, スクロールの高さ) {
   インデックスを "" にします。
   (i = 0 とします; i < arr.length; i++) {
                スクロール高さ >= this.hotCityHeight && スクロール高さ < arr[0]) {
                    インデックス = 0;
                } そうでない場合 (スクロール高さ >= arr[i - 1] && スクロール高さ < arr[i]) {
                    インデックス = i;
                }
            }
            インデックスを返します。
        },
        // スクロール距離を計算する scroll(e) {
            scrollTop を e.detail.scrollTop にします。
            scrollArr = this.heightArr; とします。
            index = this.calculateIndex(scrollArr, scrollTop); とします。
            this.currentIndex = インデックス;
        },

完成したコードは次のとおりです。

作成された() {
        _this = this とします。
        _this.mapCtx = wx.createMapContext("myMap");
        // APIコアクラスをインスタンス化します qqmapsdk = new QQMapWX({
            キー: MAP_KEY、
        });
 
        // 全国の都市リストを取得する qqmapsdk.getCityList({
            成功: 関数 (res) {
                リストをres.result[0].concat(res.result[1], res.result[2])とします。
                _this.allCity = リスト;
                _this.cityList = _this.pySegSort(リスト);
            },
            失敗: 関数 (エラー) {
                コンソールエラー(エラー);
            },
            完了: 関数 (res) {
                コンソールログ(res);
            },
        });
    },
    マウント() {
        // 人気の都市ボックスの高さを取得します。let query = wx.createSelectorQuery().in(this);
        クエリ
            .select(".hot-city")
            .boundingClientRect((データ) => {
                高さ = データ。
            })
            .exec();
 
       
        // 各文字カテゴリのブロックの高さを取得します setTimeout(() => {
            クエリを wx.createSelectorQuery().in(this); にします。
            クエリ
                .selectAll(".cityList")
                .boundingClientRect((データ) => {
                    console.log(data, "各都市の分類の高さ");
                    this.letterBoxHeight = データ;
                    this.heightArr = this.getHeight();
                })
                .exec();
        }, 1000);
    },
    メソッド: {
        // 都市リストをアルファベット順に並べ替える pySegSort(arr) {
            if (!String.prototype.localeCompare) が null を返す;
            文字を "*ABCDEFGHJKLMNOPQRSTWXYZ" とします。split("");
            let zh = "これは非常にシンプルでエレガントな文です。ここに書き留めておきます。私は...
            セグメントを [] とします。
            電流を流す;
            文字.forEach(関数(項目, i) {
                curr = { 文字: アイテム、 ID: アイテム、 データ: [] };
                arr.forEach(関数 (item2) {
                    もし (
                        (!zh[i - 1] || zh[i - 1].localeCompare(item2.fullname) <= 0) &&
                        項目2.fullname.localeCompare(zh[i]) == -1
                    ){
                        curr.data.push(item2);
                    }
                });
                (通貨データの長さ)の場合{
                    curr.data.sort(関数(a, b) {
                        a.fullname.localeCompare(b.fullname) を返します。
                    });
                    segs.push(curr);
                }
            });
            セグメントを返します。
        },
        // 右側の文字をクリックします letterClick(letter, i) {
            this.letterIndex = i;
            this.currentIndex = i;
            this.childViewId = 文字;
            タイムアウトを設定する(() => {
                this.letterIndex = -1;
            }, 500);
        },
        // 各エリアの高さを計算する getHeiht() {
            n = this.hotCityHeight とします。
            arr = [] とします。
            this.letterBoxHeight.forEach((item) => {
                n = n + アイテムの高さ;
 
                arr.push(n);
            });
            arr を返します。
        },
        インデックスを計算します(arr, スクロールの高さ) {
            インデックスを "" にします。
            (i = 0 とします; i < arr.length; i++) {
                スクロール高さ >= this.hotCityHeight && スクロール高さ < arr[0]) {
                    インデックス = 0;
                } そうでない場合 (スクロール高さ >= arr[i - 1] && スクロール高さ < arr[i]) {
                    インデックス = i;
                }
            }
            インデックスを返します。
        },
        // スクロール距離を計算する scroll(e) {
            scrollTop を e.detail.scrollTop にします。
            scrollArr = this.heightArr; とします。
            index = this.calculateIndex(scrollArr, scrollTop); とします。
            this.currentIndex = インデックス;
        },
}
<スクロールビュー scroll-y スタイル="高さ: 1400rpx" :scroll-into-view="childViewId" @scroll="スクロール">
            <!-- 人気の都市 -->
            <view class="hot-city">
                <p>人気の都市</p>
                <ul>
                    <li
                        v-for="(item, idx) が hotCityList 内"
                        :key="idx​​"
                        :class="fixedPosition === 項目 ? '選択済み' : ''"
                        @click="都市を選択(項目)"
                    >
                        {{ アイテム }}
                    </li>
                </ul>
            </ビュー>
            <!-- アルファベット順リスト -->
            <view class="letterAz">
                <表示
                    v-for="(item, idx) in letterAz"
                    :key="idx​​"
                    クラス="文字項目"
                    :class="currentIndex === idx ? '選択済み' : ''"
                    @click="letterClick(item, idx)"
                >
                    {{ アイテム }}
                    <view v-show="letterIndex === idx" class="pop-item">{{ item }}</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)">{{
                    要素のフルネーム
                } } } 表示>
            </ビュー>
</スクロールビュー>
// 人気の city.hot-city {
    パディング: 38rpx 32rpx;
    p {
        フォントサイズ: 28rpx;
        行の高さ: 40rpx;
        色: #999999;
        下部マージン: 32rpx;
    }
    ul {
        ディスプレイ: フレックス;
        flex-wrap: ラップ;
        & li {
            背景: rgba(0, 0, 0, 0.04);
            境界線の半径: 16rpx;
            フォントサイズ: 28rpx;
            色: #000000;
            テキスト配置: 中央;
            マージン: 8rpx;
            パディング: 16rpx 46rpx;
        }
        & li.selected {
            背景: rgba(45, 200, 77, 0.12);
            境界線: 0.66rpx 実線 #046a38;
            色: #046a38;
        }
    }
}
// アルファベットリスト.letterAz {
    位置: 固定;
    右: 29rpx;
    上: 380rpx;
    フォントサイズ: 20rpx;
    行の高さ: 28rpx;
    色: rgba(0, 0, 0, 0.55);
    .letter-item {
        位置: 相対的;
        上マージン: 4rpx;
        .pop-item {
            位置: 絶対;
            右: 165%;
            下部: -100%;
            幅: 96rpx;
            高さ: 96rpx;
            背景: #ffffff;
            境界線: 0.66rpx 実線 rgba(0, 0, 0, 0.12);
            ボックスのサイズ: 境界線ボックス;
            ボックスの影: 0 10rpx 24rpx rgba(0, 0, 0, 0.08);
            境界線の半径: 100%;
            テキスト配置: 中央;
            行の高さ: 96rpx;
            フォントサイズ: 40rpx;
            色: rgba(0, 0, 0, 0.85);
        }
    }
    .letter-item.selected {
        色: #046a38;
    }
}
// 都市リスト.cityList {
    左マージン: 32rpx;
    右マージン: 66rpx;
    上マージン: 20rpx;
    .city-letter {
        フォントサイズ: 28rpx;
        行の高さ: 40rpx;
        色: #999999;
    }
    .都市名 {
        フォントサイズ: 28rpx;
        行の高さ: 40rpx;
        色: #000000;
        パディング: 32rpx 0;
        下境界線: 2rpx 実線 rgba(0, 0, 0, 0.12);
    }
}

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • WeChatアプレットが左右連携を実現
  • WeChatアプレットがメニューの左右連動を実現
  • WeChatアプレットがショッピングページの左右連携を実現
  • WeChatアプレットは左右連動の実戦記録を実現
  • WeChatアプレットのスクロールビューが左右連動効果を実現

<<:  MySQL の挿入ステートメントの使用実体験

>>:  アイデアがWebプロジェクトを公開した後、Tomcatサーバーがプロジェクトとそのソリューションを見つけることができません

推薦する

Dockerコンテナを閉じずに終了する方法の詳細な説明

Docker コンテナに入った後、コンテナを終了すると、コンテナは Exited 状態に変わります。...

フォント宝庫 50 種類の素晴らしい無料英語フォントリソース パート 2

デザイナーは独自のフォント ライブラリを持っているため、プロジェクトの設計時にすぐに使用できます。今...

Vue2.x プロジェクトのパフォーマンス最適化のためのコード最適化の実装

目次1 v-ifとv-showの使用2. 計算と監視を区別する3 v-for トラバーサルでは、アイ...

W3C チュートリアル (12): W3C SOAP アクティビティ

Web サービスは、アプリケーション間の通信に関係しています。SOAP は、Web サービス間の X...

JSscriptタグの属性は何ですか

JS スクリプト タグの属性は何ですか? charset : オプション。 src 属性で指定された...

リモート接続を許可するようにMySQLを変更する方法

MySQLリモート接続の問題に関しては、会社で働いているときに誰かのコンピュータに保存されているMy...

htmlダウンロード機能の詳しい説明

新しいプロジェクトは基本的に終了しました。フロントエンドとバックエンドを分離して統合を完了したのは初...

Linux の fsevents モジュールによって発生する npm ls エラーの解決方法の詳細な説明

Mac で開発されたプロジェクトがあり、パッケージ npm i がインストールされており、すべて正常...

Mysql5.7.14 インストールと設定方法操作グラフィックチュートリアル(パスワード問題解決)

この記事は主に、以前のインストール方法を使用して MySQL 5.7.14 をインストールするときに...

MySQLでグローバル変数とセッション変数を設定する2つの方法の詳細な説明

1. MySQL でグローバル変数を変更するには 2 つの方法があります。方法 1: my.ini ...

Svelte の Defer Transition を Vue で実装する方法

最近、Rich Harris の <Rethinking Reactivity> ビデオ...

CentOS 7 で RPM を使用して mysql5.7.13 をインストールする

0. 環境この記事のオペレーティング システム: CentOS 7.2.1511 x86_64 My...

jQuery プロジェクトで重複送信を防ぐ方法

新しいプロジェクトでは、axios によって重複した送信を防ぐことができますが、古いプロジェクト (...

Alibaba Cloud ECS クラウド サーバー (Linux システム) は、MySQL をインストールした後にリモートで接続できません (落とし穴)

昨日、1年間使用していた Alibaba Cloud サーバーを購入しました。システムは Linux...

Ubuntu 18.04 に Nvidia グラフィック カード ドライバーをインストールするチュートリアル (画像とテキスト付き)

0. 事前準備BIOS でセキュア ブートを無効にします。無効にしないと、サードパーティ ソースを...