ドラッグ効果を実現するための純粋なCSSコード

ドラッグ効果を実現するための純粋なCSSコード

想像力を働かせれば、CSS でもドラッグ効果を実現できます。

1. ドラッグ効果の例

これはモバイルデバイスでは非常に一般的な効果です。以下のQidian中国語ウェブサイト[1]のタッチスクリーンバージョンのように、押してドラッグすることができます。

このような効果は、JS を使用すると簡単に実現できます。より多くの計算、より重要なシナリオ、そしてより多くのコードが必要になるだけです。しかし、よく考えてみると、CSS でこの効果をほぼ実現できることがわかりました。読み進めてみましょう。

2. CSS実装の原則

従来の Web では、ページのスクロールは一般的な操作であり、マウス ホイールを使用するか、スクロール バーを直接ドラッグして操作します。ただし、モバイルデバイスでは異なります。指でページをドラッグするだけでスクロールできます。通常、ページは垂直方向または水平方向にスクロールしますが、両方向にスクロールできるとしたらどうなるでしょうか?例えば

.ドラッグボックス{
  幅: 300ピクセル;
  高さ: 300px;
  オーバーフロー:自動
}
.dragcon{
  幅: 500ピクセル;
  高さ: 500px;
}

内部要素の幅と高さがコンテナよりも大きい限り、両方向へのスクロールが可能になります( overflow:autoを設定することを忘れないでください)。以下を参照してください。

通常、マウスホイールは一度に一方向にしかスクロールできません( Shiftキーを押しながらスクロールすると反対方向にスクロールできます)が、モバイルデバイスでは、以下に示すようにコンテンツを直接ドラッグしてスクロールできます。

次に、コンテンツ領域とともにスクロールする要素をコンテンツの中央に追加します。

次に、テキストを隠します

少しだるい感じがしますか?原理はとても簡単です!

3. CSS実装の詳細

まず、ドラッグ ターゲットとドラッグ コンテナーのサイズ関係を決定します。ドラッグ ターゲットのサイズがw * hであると仮定すると、サイズ関係を取得するのは簡単です。内部サイズはコンテナーの 2 倍からドラッグ ターゲットのサイズを引いたものになります。

.ドラッグボックス{
  幅: 100%;
  高さ: 100%;
}
.dragcon{
  幅: calc(200% - w);
  高さ: calc(200% - h);
}

動的な画像を使用して次のように説明します(中央のオレンジ色のブロックはドラッグターゲットを表します)

4. CSSレイアウト

次に、この機能をページに追加する必要があります。次の 2 つのレイアウトがあります。

1. 固定位置

以前のレイアウトをページに直接追加し、固定位置を追加します

<本文>
  ...ページ上の他の要素 <div class="dragbox">
    <div class="dragcon"></div>
    <div class="ball"></div> <!--要素をドラッグ-->
  </div>
</本文>

主なスタイルは次のとおりです

.ドラッグボックス{
  位置: 固定;
  左: 0;
  上: 0;
  右: 0;
  下部: 0;
  オーバーフロー:自動
}

階層関係は以下のとおりです

この方法では、ドラッグボックスはページの元の部分を確実にカバーするため、ドラッグ時にpointer-events: none;も追加する必要があります。同時に、 pointer-events: allも追加します。

.ドラッグボックス{
  /*...*/
  ポインタイベント: なし;
}
。ボール{
  /*...*/
  ポインタイベント: すべて;
}
.dragbox.active{
  /*...*/
  ポインタイベント: すべて;
}

JSを使用すると、押されたときに外側のコンテナをスクロールさせることができます。

ball.addEventListener('touchstart',(ev)=>{
   dragbox.classList.add('アクティブ');
})
document.addEventListener('touchend',()=>{
   dragbox.classList.remove('active');
})

実際の効果は次の通りです

完全なコードは https://codepen.io/xboxyan/pen/PobwxBK からアクセスできます (PC でアクセスするにはモバイル モードをオンにしてください)

以下のQRコードを直接スキャンすることもできます

1. 絶対的な位置付け + 階層

固定された配置レベルの影響により、以前のレイアウトでは JS を使用してコンテナーの状態を動的に変更する必要があります。元のページに影響を与えずにドラッグを実現する方法はありますか?絶対位置使用したこのレイアウトを見てみましょう

ここでは、次のように元のページをdivコンテナで囲む必要があります。

<本文>
  <div class="dragbox">
    <div class="dragcon"></div>
    <div class="ボール"></div>
  </div>
  <div class="body"> <!--ページスクロールを実現するには単一のレイヤーを使用します-->
    ...ページ上の他の要素</div>
</本文>

主なスタイルは次のとおりです

.ドラッグボックス{
  位置: 絶対;
  幅: 100%;
  高さ: 100%;
  オーバーフロー:自動;
}
。体{
  位置: 相対的;
  高さ: 100%;
  オーバーフロー:自動;
}
。ボール{
  位置: 相対的;
  z-index: 10; /*ドラッグターゲットのレベルを高く設定*/
}

階層は次のようになります

ここでは、元のページコンテンツがドラッグボックスドラッグターゲットの間に階層的に配置されているため、ドラッグ時に元のページのスクロールには影響がなく、JS 処理も必要ありません。

完全なコードは https://codepen.io/xboxyan/pen/bGBNQxL からアクセスできます (PC でアクセスするにはモバイル モードをオンにしてください)

以下のQRコードを直接スキャンすることもできます

ヒント: 上記の 2 つのレイアウト方法のうち、最初の方法はより適応性が高く、既存のプロジェクトに影響を与えません。2 番目の方法はより優れたエクスペリエンスを提供しますが、 div をページ スクロール コンテナーとして使用し、ページ構造に特定の変更を加えます。実際の状況に応じて選択できます。

5. CSSは他の機能を実装する

1. 吸着機能

多くの場合、記事の冒頭の図に示すように、端をドラッグするときに自動的に端にスナップする必要があります。では、吸着に関連する特性は何でしょうか?

答えはCSSスクロールスナップ[2]です。

<本文>
  ...ページ上の他の要素 <div class="dragbox">
    <div class="dragcon">あ</div>
    <div class="dragcon">B</div>
    <div class="ボール"></div>
  </div>
</本文>

主なスタイルは次のとおりです

.ドラッグボックス{
  ...
  scroll-snap-type: x 必須;
}
.dragcon{
  スクロールスナップ位置合わせ: 開始;
}

実際の効果は次の通りです

完全なコードは https://codepen.io/xboxyan/pen/XWNJyPw からアクセスできます (PC でアクセスするにはモバイル モードをオンにしてください)

以下のQRコードを直接スキャンすることもできます

1. 初期位置を設定する

デフォルトでは、ドラッグ ターゲットは右下隅にのみあります。 左下隅に移動するにはどうすればよいでしょうか。とても簡単です。ここでのドラッグはスクロール コンテナーによって実装されるため、scrollLeft または scrollTop を変更するだけで済みます

ドラッグボックスの左スクロール = 999;
ドラッグボックスのスクロールトップ = 999;

さらに、要素のオートフォーカス機能を使用して、可視範囲に自動的にフォーカスを合わせることで、純粋な HTML で実装することもできます。

<div class="dragcon">
  ...
  <button class="pos" autofocus></button> <!--自動フォーカス要素を追加します-->
</div>

たとえば、初期位置を左上隅にしたい場合は、右下隅にオートフォーカス要素を追加するだけです(もちろん、非表示にするには透明度も設定する必要があります)〜

1. 境界線を設定する

ドラッグ先の境界は画面の端になります。スペースを残す必要がある場合もあります。これは CSS で簡単にできます。左/上/右/下パディング境界線などをさまざまな方法で変更できます。

.ドラッグボックス{
  左: 10px;
  上: 10px;
  右: 10px;
  下: 10px;
  /*長方形: 10px;*/
}
.ドラッグボックス{
  パディング: 10px;
}

VI. 説明と要約

当初は互換性に問題はないだろうと考えていましたが、実際にテストしてみると、Safari のスクロール コンテナーの問題を中心に、iOS に多くの問題があることがわかりました。例えば、iOSの下位バージョンではスムーズにスクロールしないため、

-webkit-overflow-scrolling:touch はスムーズなスクロールと自動吸着を実現できますが、階層の問題が発生します。一部のドキュメントでは、このプロパティを設定すると、最高レベルのネイティブスクロールコンテナーが作成される、と説明されています。最初の固定レイアウトもあります。デフォルトでpoint-events: noneが設定されていてtouchstart後にautoに設定されている場合、iOS ではスクロールが失敗しますが、逆にすると機能します (デモは iOS と互換性があります)。

利点としては、CSS の柔軟性を継承し、コストがほぼゼロで、再利用が容易で、遅延のないネイティブスクロールを活用できることが挙げられます。

ただし、いくつか制限があります。ドラッグ先のサイズが固定されていない場合は、JS を使用して取得する必要がある場合があります。もちろん、比較すると、これは依然として非常に費用対効果の高い実装方法です。

今振り返ってみると、あまり目立たないプロパティは使っていませんでした (scroll-snap は 1 つかもしれませんが、あくまで補助的な機能です)。主な効果は一般的なものでした。その後、連想と発散を通じて、日々の積み重ねに基づいてネイティブ機能を十分に探求し、最終的に必要なインタラクションを完成させ、この記事に至りました。

読んでいただきありがとうございます。これが私の将来の仕事のインスピレーションになれば幸いです。

参考文献

[1] Qidian中国語ウェブサイト: https://m.qidian.com/

[2] CSSスクロールスナップ: https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Scroll_Snap

純粋な CSS でドラッグ アンド ドロップ効果を実装するコードに関するこの記事はこれで終わりです。CSS でドラッグ アンド ドロップ効果を実装する方法に関する関連コンテンツの詳細については、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

<<:  Angularの親子コンポーネント通信の詳細な説明

>>:  Linux のメモリ管理とアドレス指定の詳細な紹介

推薦する

Dockerでのpython3.8イメージのインストールについて

Docker Hub公式サイト1. Pythonミラーを検索するdocker 検索 python 2...

LeetCode の SQL 実装 (183. 注文をしたことがない顧客)

[LeetCode] 183.注文しない顧客Web サイトに、Customers テーブルと Or...

MySQL 5.7 で業務を停止せずに従来のレプリケーションを GTID レプリケーションに変更する例

GTID の利点により、従来のファイル POS ベースのレプリケーションを GTID ベースのレプリ...

JS、CSS スタイルのリファレンスの記述

CS: ... 1. <link type="text/css" href...

Windows での MySQL データベースのマスター/スレーブ構成チュートリアル

WindowsでMySQLデータベースのマスターとスレーブを構成する詳細なプロセスは次のとおりです。...

linxu での Svn ワンクリック インストール シェル スクリプトの詳細な説明

#!/bin/bash #SVNをダウンロード yum -y サブバージョンをインストールします ...

Javascript での JSBridge に関する予備的研究

目次JSBridgeの起源JSBridgeの双方向通信原理JSはネイティブを呼び出すネイティブコール...

Vueの監視プロパティの詳細

目次1.watchは一般的なデータ(数値、文字列、ブール値)の変更を監視します。 1. 数値2. 文...

Kubernetes コントローラーとラベルの簡単な分析

目次01 k8sの一般的なコントローラーRCコントローラーデプロイメント コントローラーステートフル...

JS でモバイルのインタラクティブ エクスペリエンスを向上させる方法

目次1. 即時フィードバック1.1 ボタンからの即時フィードバック1.2 継続的なフィードバック1....

MySQL 5.7 で my.ini ファイルが見つからない場合の解決策

my.ini とは何ですか? my.ini は、MySQL データベースで使用される設定ファイルです...

ネイティブ JS カプセル化 vue タブ切り替え効果

この記事の例では、ネイティブJSカプセル化vueタブ切り替えの具体的なコードを参考までに共有していま...

MySQL無料インストール版を解凍した後にパスワードが見つからない問題を解決する方法

1. mysql-8.0.21-winx64を解凍する2. 環境変数を設定し、アドレスをbinフォル...