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

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

前述の

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

推薦する

Ubuntu 14.04 に FTP サーバーをインストールするための実装手順

目次インストールソフトウェア管理匿名アクセスモード設定ファイルを変更するクライアントがサーバーにログ...

Windows10でのMySQL 5.7.21のインストールと設定のチュートリアル

この記事では、MySQL 5.7.21 のインストールと設定方法を記録し、皆様と共有します。 1. ...

JS 手ぶれ補正機能の実装と使用シナリオ

目次1. 手ぶれ補正機能とは何ですか? 1. なぜ手ぶれ補正機能が必要なのでしょうか? 2. 手ぶれ...

Windows Server 2016 でサービスを展開する方法 (グラフィック チュートリアル)

導入インストールするシステムの数が多い場合、USB フラッシュ ドライブまたは CD を使用した手動...

幅と高さが可変の要素を中央に配置するための CSS ソリューション

1. 水平中央公開コード: html: <div class="parent&quo...

DockerにNginxをインストールする方法

DockerにNginxをインストールするNginx は、IMAP/POP3/SMTP サービスも提...

MySQL で乱数を生成し、文字列を連結する方法の例

この記事では、MySQL が乱数を生成し、文字列を連結する方法について例を使用して説明します。ご参考...

MacでNodeとnpmを完全にアンインストールする方法

npmアンインストール sudo npm アンインストール npm -g この文に遭遇して npm ...

VMware で Nginx+KeepAlived クラスタ デュアルアクティブ アーキテクチャを展開する際の問題と解決策

序文負荷分散には nginx を使用します。アーキテクチャのフロントエンドまたは中間層として、トラフ...

Mysql でサーバーの UUID を変更する方法

問題の原因:スレーブサーバーがクローンマスターサーバーである場合、server-uuidの値は同じで...

Angular CLI リリース パスの構成項目の簡単な分析

序文プロジェクトのリリースでは、常に特定の状況に応じたパッケージ化が必要です。Angular CLI...

Vueはダイアログのカプセル化を実装します

目次Vue2 ライティングVue3プラグインのバージョンの記述Vue3 動的コンポーネントの記述書き...

Linux システムファイル共有 samba 設定チュートリアル

目次sambaをアンインストールしてインストールする新しい共有パスを作成し、権限を設定するSamba...

Linux の総合システム監視ツール dstat の詳細な例

オールラウンドなシステム監視ツール dstat dstat は、vmstat、iostat、nets...