Swiperでスライド要素が1つの時、カスタムナビゲーションを非表示にする

Filed under: JavaScript,swiper — kdcs @ 25年11月6日 木曜日

swiperでページネーションやナビゲーションボタンを.swiperの外側に出して表示位置をカスタマイズしているとき、スライド要素が1つしかない場合はナビゲーションを非表示にしておきたい。

以下のオプション設定で、スライド要素の数を確認し、1つの場合はstyleでdisplay:noe;を付けて非表示にする。
※基本的には、’#eventAd .custom-navigation’これだけをdisplay:noneにすればよい

const swiper2 = new Swiper('.eventAdSlider', {
  loop: true,
  parallax: true, // パララックスさせる
  allowTouchMove: false, // マウスでのスワイプを禁止
  speed: 1500,
  autoplay: {
    delay: 5000, // 5秒ごとに自動再生
    disableOnInteraction: false, // ユーザー操作後も自動再生を継続
  },
  pagination: {
    el: '#eventAd .swiper-pagination',
  },
  navigation: {
    nextEl: '#eventAd .swiper-button-next',
  },
  on: {
    init: function () {
// スライド要素が1つの場合、カスタムナビ非表示(loop:true の場合、クローン要素も含まれるので注意)
      const realSlideCount = this.slides.filter(slide => !slide.classList.contains('swiper-slide-duplicate')).length;
      if (realSlideCount <= 1) {
        document.querySelector('#eventAd .custom-navigation').style.display = 'none';
        document.querySelector('#eventAd .swiper-button-next').style.display = 'none';
        document.querySelector('#eventAd .swiper-button-prev').style.display = 'none';
        document.querySelector('#eventAd .swiper-pagination').style.display = 'none';
      }
    }
  }
});

非表示にする必要が無い場合はこちら

const swiper2 = new Swiper('.eventAdSlider', {
  loop: true,
  parallax: true, // パララックスさせる
  allowTouchMove: false, // マウスでのスワイプを禁止
  speed: 1500,
  autoplay: {
    delay: 5000, // 5秒ごとに自動再生
    disableOnInteraction: false, // ユーザー操作後も自動再生を継続
  },
  pagination: {
    el: '#eventAd .swiper-pagination',
  },
  navigation: {
    nextEl: '#eventAd .swiper-button-next',
  },
});

スマホでモーダルメニューを開閉する時にページ内での位置を保持させる

Filed under: JavaScript — kdcs @ 25年10月9日 木曜日

スマートフォンでページの途中でモーダルメニューを開閉したときにページ内での位置を保持して再表示させる方法。

※コード内でスクロール位置を先に取得して保存させないと、cssのスタイルが先に実行されて「top: 0px」になってしまい、メニューの開閉でページトップに戻されてしまう。

動作OKのコード(scrollアニメ表示版があります)

const trigger = document.querySelector('.globalMenu');
const body = document.body;
const modal = document.getElementById('globalNavArea');
let scrollPosition = 0;

const toggleNav = () => {
  const isOpening = !trigger.classList.contains('is-active'); // 開くかどうかを事前に判定

  if (isOpening) {
    scrollPosition = window.scrollY; // スクロール位置を先に取得
    console.log('保存する scrollPosition:', scrollPosition);
  }

  const isActive = trigger.classList.toggle('is-active');
  body.classList.toggle('is-nav-opened', isActive);
  body.classList.toggle('is-nav-close', !isActive);

  if (isActive) {
    body.style.top = `-${scrollPosition}px`;
    modal.scrollTop = 0;
  } else {
    body.style.top = '';
    window.scrollTo(0, scrollPosition);
  }
};

trigger.addEventListener('click', toggleNav);

こちらはモーダルウィンドウメニューを開いたときにscrollアニメを5秒間表示させるスクリプト
※メニュー開閉時のページ位置保持も修正されています

// 読み込み完了するまでグローバルメニューを非表示にする
// style.cssで「#globalNav」をdisplay: none;にしておく
window.onload = function () {
  document.getElementById('globalNav').style.display = 'block';

// スマホ グローバルメニュー(メニューを開くと5秒間scrollアニメを表示する) ----
const trigger = document.querySelector('.globalMenu');
const body = document.body;
const modal = document.getElementById('globalNavArea');
const scrollNotice = document.querySelector('.sp_block.gnScroll');
let scrollPosition = 0;

let fadeOutTimer = null;
let hideTimer = null;

const toggleNav = () => {
  const isOpening = !trigger.classList.contains('is-active');

  if (isOpening) {
    scrollPosition = window.scrollY;
    console.log('保存する scrollPosition:', scrollPosition);
  }

  const isActive = trigger.classList.toggle('is-active');
  body.classList.toggle('is-nav-opened', isActive);
  body.classList.toggle('is-nav-close', !isActive);

  if (isActive) {
    // スクロールを止める
    body.style.position = 'fixed';
    body.style.top = `-${scrollPosition}px`;
    body.style.left = '0';
    body.style.right = '0';
    modal.scrollTop = 0;

    clearTimeout(fadeOutTimer);
    clearTimeout(hideTimer);

    if (scrollNotice) {
      scrollNotice.style.display = 'block';
      scrollNotice.classList.remove('fade-out');

      fadeOutTimer = setTimeout(() => {
        scrollNotice.classList.add('fade-out');
      }, 5000);

      hideTimer = setTimeout(() => {
        scrollNotice.style.display = 'none';
        scrollNotice.classList.remove('fade-out');
      }, 5500);
    }
  } else {
    // スクロールを戻す
    body.style.position = '';
    body.style.top = '';
    body.style.left = '';
    body.style.right = '';
    window.scrollTo(0, scrollPosition);

    clearTimeout(fadeOutTimer);
    clearTimeout(hideTimer);

    if (scrollNotice) {
      scrollNotice.style.display = 'none';
      scrollNotice.classList.remove('fade-out');
    }
  }
};

trigger.addEventListener('click', toggleNav);

古いios safariでも非jQueryでページトップへのスムーズスクロールをさせる方法

Filed under: css,JavaScript — kdcs @ 25年10月8日 水曜日

ページトップへのスクロールをスムーズに移動させるためにjQuery+smoothscroll.jsを使用していたが、以下のようにjavascriptだけで動作するようにした。

common.js

const topButton = document.querySelector('#page-top-js');

topButton.addEventListener('click', () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth'
  });
});

これでは古いiosのsafariでは「behavior: ‘smooth’」がサポートされていないので、「smoothscroll.polyfill」を使う。

footer.php
※common.js内の記述より先に読み込む必要があるのでfooter.phpに記述する。

<script src="https://unpkg.com/smoothscroll-polyfill/dist/smoothscroll.min.js"></script>
<script>
  // ポリフィルを初期化
  smoothscroll.polyfill();
</script>

但し、2022年4月時点で最新のSafari15.4にて、scroll-behaviorが使用できるようになっているので最近のブラウザだけに対応すればよければ以下のcssでOK。

html {
  scroll-behavior: smooth;
}

GLightboxの導入方法

Filed under: functions.php,JavaScript — kdcs @ 25年9月21日 日曜日

jQueryに依存しないlightbox「GLightbox」をWordPressに導入する方法

GLightboxのダウンロード先はこちら

ダウンロード後に解凍。必要なファイルはdistフォルダ内「glightbox.min.cssとglightbox.min.js」
オプション設定はcommon.js内で行う。

cdnでGLightboxのCSSとJSをテーマに読み込ませる
functions.php

function mytheme_enqueue_scripts() {
  // GLightboxのCSS
  wp_enqueue_style('glightbox-css', 'https://cdn.jsdelivr.net/npm/glightbox/dist/css/glightbox.min.css');

  // GLightboxのJS
  wp_enqueue_script('glightbox-js', 'https://cdn.jsdelivr.net/npm/glightbox/dist/js/glightbox.min.js', array(), null, true);

  // 初期化スクリプト
  wp_add_inline_script('glightbox-js', 'const lightbox = GLightbox({ selector: ".glightbox" });');
}
add_action('wp_enqueue_scripts', 'mytheme_enqueue_scripts');

オプション設定
common.js

const lightbox = GLightbox({
  selector: '.glightbox',
  touchNavigation: true,
  loop: true,
  zoomable: false,
});

画像のaタグに class=”glightbox” を自動で追加する
functions.php

function add_glightbox_class_to_image_links($content) {
  // aタグのhrefが画像ファイルの場合にclass="glightbox"を追加
  $content = preg_replace_callback(
    '/<a\s+([^>]*href=["\']([^"\']+\.(jpg|jpeg|png|gif|webp))["\'][^>]*)>/i',
    function($matches) {
      $tag = $matches[0];
      // すでにclass属性があるか確認
      if (strpos($tag, 'class=') !== false) {
        // class属性にglightboxを追加
        $tag = preg_replace('/class=["\']([^"\']*)["\']/', 'class="$1 glightbox"', $tag);
      } else {
        // class属性がない場合は追加
        $tag = str_replace($matches[0], '<a ' . $matches[1] . ' class="glightbox">', $tag);
      }
      return $tag;
    },
    $content
  );
  return $content;
}
add_filter('the_content', 'add_glightbox_class_to_image_links');

※画像ファイルの形式を「jpg|jpeg|png|gif|webp」にしているのでpdfファイルは除外される

デフォルトの投稿タイプpostの記事だけに適用する記述

function add_glightbox_class_to_image_links($content) {
  // デフォルト投稿タイプの個別ページのみ適用
  if (is_singular('post') && is_main_query() && in_the_loop()) {
    $content = preg_replace_callback(
      '/<a\s+([^>]*href=["\']([^"\']+\.(jpg|jpeg|png|gif|webp))["\'][^>]*)>/i',
      function($matches) {
        $tag = $matches[0];
        if (strpos($tag, 'class=') !== false) {
          $tag = preg_replace('/class=["\']([^"\']*)["\']/', 'class="$1 glightbox"', $tag);
        } else {
          $tag = str_replace($matches[0], '<a ' . $matches[1] . ' class="glightbox">', $tag);
        }
        return $tag;
      },
      $content
    );
  }
  return $content;
}
add_filter('the_content', 'add_glightbox_class_to_image_links');

・is_singular(‘post’):通常の投稿だけに限定
・is_main_query():メインクエリ(本文表示)だけに限定
・in_the_loop():WordPressループ内だけに限定
これで、固定ページやカスタム投稿、ウィジェットなどには影響せず、通常の投稿記事だけに glightbox クラスが追加されるようになる。

lightbox機能の速度はcssのanimationで行っている。
以下、アニメーションスピードのカスタマイズ

/*------------------------------------------------
  GLightbox css custom animation
--------------------------------------------------*/
.gfadeIn {
  -webkit-animation: gfadeIn 0.5s ease;
  animation: gfadeIn 0.5s ease !important;
}
.gfadeOut {
  -webkit-animation: gfadeOut 0.5s ease;
  animation: gfadeOut 0.8s ease !important;
}
.gzoomIn {
  -webkit-animation: gzoomIn 0.5s ease;
  animation: gzoomIn 0.5s ease !important;
}
.gzoomOut {
  -webkit-animation: gzoomOut 0.8s ease;
  animation: gzoomOut 0.8s ease !important;
}

Swiperでスライドに動画を使う

Filed under: JavaScript,swiper — kdcs @ 25年9月17日 水曜日

copilot

基本的な実装方法
html

<div class="swiper-container">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <video src="video01.mp4" controls></video>
    </div>
    <div class="swiper-slide">
      <video src="video02.mp4" controls></video>
    </div>
    <div class="swiper-slide">
      <video src="video03.mp4" controls></video>
    </div>
  </div>
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

・controls を付けると再生・停止ボタンが表示されます。
・autoplay や loop などの属性も使えるが、ユーザー体験を考慮して慎重に設定する必要あり

スライド切り替え時に動画を自動再生・一時停止する
JavaScriptでSwiperのイベントを使って、スライドが切り替わるタイミングで動画を制御できる
javascript

const swiper = new Swiper('.swiper-container', {
  on: {
    transitionStart: function () {
      document.querySelectorAll('video').forEach(video => video.pause());
    },
    transitionEnd: function () {
      const activeSlide = document.querySelector('.swiper-slide-active');
      const video = activeSlide.querySelector('video');
      if (video) video.play();
    }
  }
});

現在表示されているスライドの動画だけが再生される
・動画ファイルのサイズが大きい場合は preload=”none” を使うと読み込みが軽くなる
・モバイル環境では autoplay が制限されることがある

Swiperで静止画と動画が混在するスライダー

実現するためのポイント
・Swiperの自動スライド(autoplay)を使う
・動画スライドが表示されたら autoplay を停止
・動画の再生が終わったら autoplay を再開

javascript

const swiper = new Swiper('.swiper-container', {
  autoplay: {
    delay: 3000,
    disableOnInteraction: false,
  },
  on: {
    slideChangeTransitionStart: function () {
      const videos = document.querySelectorAll('video');
      videos.forEach(video => video.pause());

      const activeSlide = document.querySelector('.swiper-slide-active');
      const video = activeSlide.querySelector('video');

      if (video) {
        swiper.autoplay.stop(); // スライド停止
        video.play();

        // 動画再生終了時にスライド再開
        video.onended = () => {
          swiper.autoplay.start();
        };
      }
    }
  }
});

・autoplay.stop() と autoplay.start() を使えば、Swiperの自動スライドを制御できる
・video.onended は動画の再生が終わったタイミングを検知する
・静止画スライドでは通常通り autoplay が動作

サイト内検索

カテゴリー

最近の投稿

↑上に戻る