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

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

前述の

この記事はとても短いです〜
主な目的は、モバイル端末上のクリックと 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システムにおける重要なサブディレクトリの問題について話す

推薦する

CSS で 3D ブック効果を実装するためのサンプル コード

さっそく、レンダリングを見てみましょうソースコードは以下のとおりです <!DOCTYPE ht...

CSS スキル コレクション - 古典の中の古典

リンク上の点線のボックスを削除しますコードをコピーコードは次のとおりです。 a:アクティブ、a:フォ...

Vue が Ref を使用してレベル間でコンポーネントを取得する手順

VueはRefを使用してレベル間でコンポーネントインスタンスを取得します例の紹介開発プロセスでは、レ...

Javascriptでオブザーバーモードを実装する方法を教えます

目次オブザーバーパターンとは何ですか?シナリオシミュレーションコードの実装コードのリファクタリング要...

Docker クリーンアップ環境操作

丁寧に掃除を始めましょう!未使用ボリュームの一覧docker ボリューム ls -qf dangli...

画像のシームレスなスクロールを実現する JavaScript タイマー

この記事では、画像のシームレスなスクロールを実現するためのJavaScriptの具体的なコードを参考...

Linux での SSH パスワードフリーログイン設定の詳細な説明

Linux サーバー A と B が 2 台あり、一方のサーバーから SSH 経由でパスワードなしで...

1つの記事でJavaScriptのクロージャ関数について学ぶ

目次変数のスコープ閉鎖の概念クロージャの使用クロージャのデメリット最後に、クロージャのメリットとデメ...

vuex名前空間の使用

目次Vuex は単一の状態ツリーを使用するため、すべてのアプリケーション状態が比較的大きなオブジェク...

MySQL 8.0.20 Window10無料インストール版設定とNavicat管理チュートリアルグラフィック詳細説明

1. MySQL 8.0.20をダウンロードして解凍するダウンロードリンク: https://dev...

jsのディープコピーを理解しましょう

目次js ディープコピーデータ保存方法浅いコピー/深いコピーとは何か一般的なディープコピーの実装1....

ミニプログラムはリストのカウントダウン機能を実装します

この記事の例では、ミニプログラムでリストカウントダウンを実装するための具体的なコードを参考までに共有...

HTML の基礎: HTML コンテンツの詳細

まずは本体から始めましょう:ウェブページを閲覧するとき、最初に目に留まるのは通常、ページの背景です。...

Linux で LVGL エミュレータをコンパイルする際のエラーの解決方法

目次1. エラー現象2. エラー分析3. エラー解決1. エラー現象仮想マシンでLVGLエミュレータ...

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

この記事では、MySQL 8.0.24のインストールチュートリアルを参考までに紹介します。具体的な内...