1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

横スクロール(スワイプ)をマウスジェクチャーも含めてなるたけ簡単に作ってみた

Last updated at Posted at 2023-07-28

ブラウザを上下に移動する縦スクロールは、普通だけれど、横スクロールはどうすれはいいか?
とても簡単でコンテナ(スクロールさせたい部分)に overflow-x: hidden というCSSを入れれば簡単にできる。

See the Pen Horizontai scroll by Mayo Tobita (@mayognaise) on CodePen.

携帯やタブレット、デスクトップのトラックパッド、もしくは横スクロール対応のマウスであればこれは完璧に動きます。

しかし、デスクトップでトラックパッドがない場合や横スクロールが対応していないマウスの場合はどうすれば良いでしょうか。

キーボードの場合、アクセシビリティ用に、コンテナに tabindex="0" を加えてください。キーボードのタブキーでコンテナをフォーカスした後、左右のキーボードで移動することができます。

マウスの場合、下についているスクロールバーをドラッグして移動させる方法がひとつありますが、多少やりずらいし、携帯のようにスクリーンをスワイプして移動させたいですよね。

残念ながら現在のところはJavascriptを使用しないといけないのです。
いろいろなJSライブラリがありますが、自分でできるだけ簡単に作ってみたい!
ということで、極力コードを少なくして作ってみました!

See the Pen Horizontal scroll with keyboard and mouse gesture including accessibility support by Mayo Tobita (@mayognaise) on CodePen.

まずは、左右のボタンから。仕組みは簡単で、ボタンを押したら、
右の場合はコンテナの幅分を増やして、左の場合はコンテナの幅分を減らしてスクロールさせる

const container = document.body.querySelector(".container");
const { width } = container.getBoundingClientRect();

// 右
container.scrollLeft += width;

// 左
container.scrollLeft -= width;

たったこれだけです。
ここでどうやってスムーズにスクロールしているのか?コンテナに scroll-behavior: smooth を入れるだけです。そうすると、スムーズに移動してくれます。

アクセシビリティ用に、ユーザーが過度なアニメーションを望まない設定をしている場合は、この設定を無効にするのを忘れないでください。

.container {
  overflow-x: auto;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion) {
  .container {
    scroll-behavior: auto;
  }
}

さて、次にスワイプの設定です。マウスイベントには、movementX という、前回からの x の値からの差分を教えてくれる便利なプロパティがあります。それを使って、スクロールさせるだけです。

const container = document.body.querySelector(".container");

container.addEventListener("mousemove", (event) => {
  container.scrollLeft -= event.movementX * 10
});

実際のコードは、コンテナ内でマウスダウンをしたときや、マウスを離したり等の設定をつける必要があります。
最終的なものはこれです。

const container = document.body.querySelector(".container");
let flag = false;

container.addEventListener("mousedown", () => (flag = true));
container.addEventListener("mouseup", () => (flag = false));
container.addEventListener("mouseleave", () => (flag = false));
container.addEventListener("mousemove", (event) => {
  flag && (container.scrollLeft -= event.movementX * 10);
});
container.addEventListener("wheel", (event) => {
  event.preventDefault();
  container.scrollLeft += (event.deltaX + event.deltaY) * 5;
});

もちろん、コードをもっと書けば、もっとなめらかに動くよう設定できますが、これが一番コードが少なくて、スワイプを実現しているのではないでしょうか。

もちろん、もっと簡単にできるなら、是非教えてください!:smiley:

読んでいただいてありがとうございました。

【追加修正】

@akebi_mhからマウスホイールを使っての修正をいただきましたのでコードを変更しました!

container.addEventListener("wheel", (event) => {
  event.preventDefault();
  container.scrollLeft += (event.deltaX + event.deltaY) * 5;
});

あと、scrollLeftはread-onlyではないので、scrollToを使わずに直接設定しました!

const x = 10;
// container.scrollTo(container.scrollLeft + x, 0);
container.scrollLeft += x;

@akebi_mhさんありがとうございます!!!

1
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?