スライドによるページめくり効果とクリックイベント問題をモバイル端末上で実装する

スライドによるページめくり効果とクリックイベント問題をモバイル端末上で実装する

前述の

この記事はとても短いです〜
主な目的は、モバイル端末上のクリックと js イベントのメカニズムによって発生する問題を要約して説明することです。
(: えーっと、実は、数文で書き終えられる記事を書かないといけないんです。私にはそれに値する力があるんです…


文章

私は最近、ページをめくるスライドという効果を必要とする小さなアクティビティを行いました。おそらく次のようになります:

デモビュー

<!-- HTML コード -->
<div class="ページコンテナ">
	<div class="page" style="background: #dc3b26">1</div>
	<div class="page" style="background: #f3b03d">2</div>
	<div class="page" style="background: #44a2f8">3</div>
</div>

CSS では、まず、ページをめくるにはスライドするので、「常に 1 つの画面だけが存在する」ことを保証する必要があります。これは、グローバル スタイル シートで制御できます。次に、「各ページ」が親要素全体を占める必要があります。ここで実際に使用する機能は、「div はブロック要素であり、外部からの力なしに垂直に配置される」というものです。

/** CSS スタイル */
html,
体{
	マージン: 0;
	パディング: 0;
	幅: 100%;
	高さ:100vh;
	オーバーフロー: 非表示;
	フォントサイズ: 60px;
}
.ページコンテナ{
	幅: 100%;
	高さ: 100%;
}
.ページコンテナ .ページ{
	幅: 100%;
	高さ: 100%;
}

JS 実装も非常にシンプルです。モバイル端末上にあるため、ジェスチャ スライド機能を実装するためにtouchstarttouchmove 、およびtouchendイベントが使用されます。

  • 開始時(押したばかり)に、この時点での指の位置を初期値として記録します。
  • 移動(タッチスライド)時には、リアルタイムの指の位置と初期指位置変数に基づいて要件の判断が行われます。この記事で紹介したシナリオでは、このステップでは通常、「移動距離」のリアルタイム割り当ても必要です。
  • 最後に(指が離れる)(または移動時に直接)仕上げ作業が実行されます。たとえば、画像が完全にスライドし、要素が終了位置に移動し、イベント リスナーがキャンセルされます。
// グローバル js を制御するファイルです // ブラウザのデフォルトの動作をグローバルに防止します document.addEventListener("touchstart",function(e){
	if(e.cancelable){
		e.preventDefault();
	}
},{受動態: false})
// {passive: false} は、前のコードに動作をリセットする必要があるかもしれないことを伝えます document.addEventListener("touchmove",function(e){
	if(e.cancelable){
		e.preventDefault();
	}
},{受動態: false})
// JavaScript コード let curPageIndex=0;
pageContainer を document.querySelector(".page-container"); とします。
let pageNumber=pageContainer.children.length; //ページ数// ドキュメントウィンドウの高さ(ここでは1画面の高さ)
cHeight=document.documentElement.clientHeight とします。
// ページコンテナの margin-top を適切な値に設定して、ビュー関数 toPage(){ に表示されるようにします。
	pageContainer.style.transition="すべて .5 秒の遷移";
	pageContainer.style.marginTop=-curPageIndex*cHeight+"px";
	
	// 変更が完了したらトランジション効果を削除します。
	pageContainer.addEventListener("transitionend",function(){
		pageContainer.style.transition="なし";
	},{once:true})
}
ページへ()

pageContainer.ontouchstart=関数(e){
	let y=e.changedTouches[0].clientY; // 指が押された垂直座標 pageContainer.ontouchmove=function(e){
		let dis=e.changedTouches[0].clientY-y; // 距離を計算する // ページコンテナの上部の余白を計算する
		mtop=-curPageIndex*cHeight+dis とします。
		(mtop>0)の場合{
			0 の場合
		}そうでない場合、mtop<-(ページ番号-1)*cHeight){
			mtop=-(ページ番号-1)*c高さ;
		}
		// リアルタイムで位置を変更します pageContainer.style.marginTop=mtop+"px";
	}
	pageContainer.ontouchend=関数(e){
		dis = e.changedTouches[0].clientY-yとします。
		// スライド距離が短すぎる場合は、スライド前の位置に戻ります if(Math.abs(dis)<=60){
			ページへ()
		}それ以外の場合(dis>0 && curPageIndex>0){
			curPageIndex--;
			ページへ()
		}それ以外の場合(dis<0 && curPageIndex<pageNumber-1){
			curPageIndex++;
			ページへ()
		}
		
		// 指が離れたら、監視イベントをキャンセルします。pageContainer.ontouchmove=null;
		pageContainer.ontouchend = null;
	}
}

これまでのところ、機能は完璧のようです。しかし今回は、最初のページにボタンを追加します。

<div class="page" style="background: #dc3b26">
	<button onclick="alert('哈哈哈哈')" class="but">クリックしてください!</button>
	1
</div>

次に、ページに移動して効果を確認します。

エラービュー

無効!

これは、上記のグローバル js ファイルに「ブラウザのデフォルト イベントを防止する」コードを追加したためです。
——モバイルブラウザでは、クリックイベントとマウススタートイベントが同時にトリガーされます。モバイル ブラウザーにはクリック イベントがないため、マウス イベントによってシミュレートされます。 :いわゆる「モバイルブラウザでの300ms遅延」問題が発生するのはこのためです1。
——また、WeChatに付属のブラウザでは「上をタッチして下に引っ張るとリバウンドする」という操作がありますが、これは実際には許可されていません。これはブラウザのデフォルト イベントでもあります。
したがって、一般的にはこれらのものを禁止する必要があります。

しかし、上記のように、すべてを禁止すると必ず何らかの問題が発生します。どうすればよいでしょうか?
H5 は「カスタム属性」を提供します。この記事のメソッドでは、現在トリガーされている要素にグローバル イベント内の特定のカスタム属性があるかどうかを完全に検出できます。ある場合は何も行いません。それ以外の場合は、デフォルトの動作を禁止するコードを実行します。
例えば

<button data-default="true" onclick="alert('哈哈哈哈')" class="but">クリックしてください!</button>

上記の「グローバル js を制御するファイル」の内容を次のように変更します。

// ブラウザのデフォルトの動作を全体的に防止する document.addEventListener("touchstart",function(e){
	if(e.target.dataset.default){
		戻る;
	}
	if(e.cancelable){
		e.preventDefault();
	}
},{受動態: false})
document.addEventListener("touchmove",function(e){
	if(e.target.dataset.default){
		戻る;
	}
	if(e.cancelable){
		e.preventDefault();
	}
},{受動態: false})

大丈夫です:

成功ビュー


実際には、別の「解決策」があります。前述のように、モバイル クリックは実際にはマウス イベントによってシミュレートされるため、mousestart イベントから開始できます。また、ボタン要素は「最初のページ」の (子) 要素であるため、イベントがバブリングしないようにする方法を使用できます。

<!-- ボタンは通常のボタンです -->
<button class="but">クリックしてください!</button>
document.querySelector(".but").addEventListener("touchstart",function(e){
	e.stopPropagation();
	alert('嘎哈哈');
}、間違い) 

完全ビュー

キャプチャとバブリングについて→

まず知っておくべきことは、マウスでボタンを押したとき、それは「ボタンをクリックする」のではなく、マウス(のボタン)がこの領域で押され、オペレーティング システムとブラウザーがこの情報を「ボタン」領域にマッピングしてロジックをトリガーするということです。
実は、マウスクリックには位置情報がありません。オペレーティングシステムは常にマウスの動きを監視しており、累積した変位に基づいて座標を計算し、ブラウザに渡します。
そして、この座標を特定の要素上のイベントに変換するプロセスを「キャプチャ」と呼ぶことができます。 「バブリング」はどうですか?説明するのは難しいですが、一つだけお分かりいただけたと思います。テレビのスイッチを押すと、テレビも押されるのです。
これは多くの記事で「泡立ちのプロセスは内側から外側へ、捕捉のプロセスは外側から内側へ」または「タマネギモデル」と呼ばれているものです。
もう 1 つのポイントは、 addEventListenerイベントの 3 番目のパラメータtrue/false 「キャプチャ/バブル」を意味することです。 (考えすぎないでください。これはブラウザが提供するイベント モデルの 1 つにすぎません。リッスンするかどうかに関係なく、イベントが発生すると、キャプチャとバブリングが常に順番に発生します)

モバイル端末でのスライドページめくり効果の実装とクリックイベントの問題に関するこの記事はこれで終わりです。スライドページめくり効果に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Android のカスタム左右または上下スライドページめくり効果
  • Android ViewPager はスライド式ページめくり効果のサンプル コードを実装します
  • NGUI はスライド式ページめくり効果のサンプルコードを実装します
  • jQueryMobile を使用してスライドページめくり効果を実現する方法
  • Androidでスライドページめくりを実現するViewFlipperの使い方を詳しく解説
  • jQueryは$.ajaxに基づいてモバイルクリックタイムアウト処理方法を設定します

<<:  Linux プラットフォームの MySQL でリモート ログインを有効にする

>>:  Linuxシステムにおける重要なサブディレクトリの問題について話す

推薦する

MySQL 5.7 解凍版のインストール、アンインストール、および文字化けしたコードの問題のグラフィック解決

1. 解凍版のインストール(1)圧縮パッケージをダウンロードし、ディスクの場所に解凍します。圧縮パッ...

Alibaba Cloud ホストが IP を使用して Web サイトにアクセスできない問題の解決策 (セキュリティ グループ ルールを構成することで解決)

Alibaba Cloud ホストを購入したばかりで、その速度を試すのが待ちきれませんでした。しか...

Nginx 502 Bad Gateway エラーの原因と解決策

Nginx 502 Bad Gateway エラーに何度か遭遇しました。ここでメモしておこうと思いま...

ウェブサイトデザインにおいて非常に重要な概念であるdiv+floatの分析

ウェブサイトの構築では、HTML と CSS に関するさまざまな問題に常に遭遇します。ウェブサイト ...

MySQL 5.7.23 のインストールと設定のグラフィックチュートリアル

この記事では、mysql5.7.23 の詳細なインストールプロセスを記録し、皆さんと共有します。 1...

QTとJavaScript間のインタラクティブデータの実装

1. QTからJSへのデータフロー1. QTはJS関数を呼び出し、JSはパラメータを通じてQTの値を...

Vueは大画面ページのスクリーン適応を実現します

この記事では、大画面ページのスクリーンアダプテーションを実現するためのVueの具体的なコードを参考ま...

Vue.js のミックスインの詳細な説明

ミックスインは、コンポーネントに分散された再利用可能な機能を柔軟な方法で提供します。 Mixin オ...

JavaScriptの擬似配列と配列の使い方と違い

擬似配列と配列JavaScript では、5 つのプリミティブ データ型を除き、関数を含め、その他す...

マークアップ言語 -

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

Linux trコマンドの使用

1. はじめにtr はテキストの一部を変換または削除するために使用されます。 tr は transl...

大きな MySQL テーブルに列を追加する方法

質問は https://www.zhihu.com/question/440231149 から参照さ...

Zabbixで指定時間内の変化値を設定する方法の詳細な説明

背景説明: 既存の負荷分散装置には、付加価値状態にある指標があります (増加するだけで減少しないため...

MySQL マスタースレーブレプリケーションプロセスの詳細な説明

1. マスタースレーブレプリケーションとは何ですか?マスター データベースの DDL および DML...

JavaScriptカルーセルの実装について

今日もとても実践的な事例です。名前を聞くだけで高度で難しそうですよね?今日はカルーセル画像の真髄を簡...