MediaWiki:Common.js

2026年9月2日 (水) 06:41時点におけるド馬 (トーク | 投稿記録)による版 (ページの作成:「→‎ここにあるすべてのJavaScriptは、すべてのページ読み込みですべての利用者に対して読み込まれます: →‎========================================================= * 外部画像ギャラリー * =========================================================: mw.hook('wikipage.content').add(function ($content) { $content.find('.ts-gallery').each(function () { var gallery = this; →‎二重初期化防止: if (gallery.d…」)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

注意: 保存後、変更を確認するにはブラウザーのキャッシュを消去する必要がある場合があります。

  • Firefox / Safari: Shift を押しながら 再読み込み をクリックするか、Ctrl-F5 または Ctrl-R を押してください (Mac では ⌘-R)
  • Google Chrome: Ctrl-Shift-R を押してください (Mac では ⌘-Shift-R)
  • Internet Explorer / Microsoft Edge: Ctrl を押しながら 最新の情報に更新 をクリックするか、Ctrl-F5 を押してください
  • Opera: Ctrl-F5を押してください
/* ここにあるすべてのJavaScriptは、すべてのページ読み込みですべての利用者に対して読み込まれます */
/* =========================================================
 * 外部画像ギャラリー
 * ========================================================= */

mw.hook('wikipage.content').add(function ($content) {

	$content.find('.ts-gallery').each(function () {

		var gallery = this;

		/* 二重初期化防止 */
		if (gallery.dataset.galleryReady === '1') {
			return;
		}

		gallery.dataset.galleryReady = '1';

		var track = gallery.querySelector('.ts-gallery__track');

		if (!track) {
			return;
		}

		/* 戻るボタン */
		var prev = document.createElement('button');
		prev.type = 'button';
		prev.className = 'ts-gallery__nav ts-gallery__prev';
		prev.innerHTML = '‹';
		prev.setAttribute('aria-label', '前の画像');

		/* 進むボタン */
		var next = document.createElement('button');
		next.type = 'button';
		next.className = 'ts-gallery__nav ts-gallery__next';
		next.innerHTML = '›';
		next.setAttribute('aria-label', '次の画像');

		gallery.appendChild(prev);
		gallery.appendChild(next);

		/* 1回に移動する距離 */
		function getStep() {

			var item = track.querySelector('.ts-gallery__item');

			if (!item) {
				return track.clientWidth * 0.85;
			}

			var style = window.getComputedStyle(track);
			var gap = parseFloat(style.columnGap || style.gap) || 0;

			return item.getBoundingClientRect().width + gap;
		}

		/* ボタン状態更新 */
		function updateButtons() {

			var maxScroll =
				track.scrollWidth - track.clientWidth;

			var scrollable = maxScroll > 5;

			gallery.classList.toggle(
				'ts-gallery--scrollable',
				scrollable
			);

			prev.disabled =
				!scrollable ||
				track.scrollLeft <= 5;

			next.disabled =
				!scrollable ||
				track.scrollLeft >= maxScroll - 5;
		}

		prev.addEventListener('click', function () {

			track.scrollBy({
				left: -getStep(),
				behavior: 'smooth'
			});
		});

		next.addEventListener('click', function () {

			track.scrollBy({
				left: getStep(),
				behavior: 'smooth'
			});
		});

		var ticking = false;

		track.addEventListener('scroll', function () {

			if (!ticking) {

				window.requestAnimationFrame(function () {
					updateButtons();
					ticking = false;
				});

				ticking = true;
			}

		}, { passive: true });

		window.addEventListener('resize', updateButtons);

		/* 画像読み込み後にも判定 */
		var images = track.querySelectorAll('img');

		images.forEach(function (image) {
			image.addEventListener('load', updateButtons);
		});

		updateButtons();
	});
});