「MediaWiki:Mobile.js」の版間の差分
(ページの作成:「→ここにある全てのJavaScriptはモバイル版サイトの利用者に影響します: →========================================================= * 外部画像ギャラリー * =========================================================: mw.hook('wikipage.content').add(function ($content) { $content.find('.ts-gallery').each(function () { var gallery = this; →二重初期化防止: if (gallery.dataset.galleryReady === '1') { return;…」) |
編集の要約なし |
||
| 120行目: | 120行目: | ||
updateButtons(); | updateButtons(); | ||
}); | }); | ||
}); | |||
/* ========================================================= | |||
* Infobox 画像スライダー | |||
* ========================================================= */ | |||
mw.hook('wikipage.content').add(function ($content) { | |||
$content.find('.ts-infobox-slider').each(function () { | |||
var slider = this; | |||
/* 二重初期化を防止 */ | |||
if (slider.dataset.infoboxSliderReady === '1') { | |||
return; | |||
} | |||
slider.dataset.infoboxSliderReady = '1'; | |||
var track = | |||
slider.querySelector('.ts-infobox-slider__track'); | |||
if (!track) { | |||
return; | |||
} | |||
var slides = | |||
track.querySelectorAll('.ts-infobox-slider__slide'); | |||
if (!slides.length) { | |||
return; | |||
} | |||
/* | |||
* 1枚だけなら矢印を作らない | |||
*/ | |||
if (slides.length === 1) { | |||
slider.classList.add( | |||
'ts-infobox-slider--single' | |||
); | |||
return; | |||
} | |||
/* ----------------------------------------- | |||
戻るボタン | |||
----------------------------------------- */ | |||
var prev = | |||
document.createElement('button'); | |||
prev.type = 'button'; | |||
prev.className = | |||
'ts-infobox-slider__nav ' + | |||
'ts-infobox-slider__prev'; | |||
prev.innerHTML = '‹'; | |||
prev.setAttribute( | |||
'aria-label', | |||
'前の画像' | |||
); | |||
/* ----------------------------------------- | |||
次へボタン | |||
----------------------------------------- */ | |||
var next = | |||
document.createElement('button'); | |||
next.type = 'button'; | |||
next.className = | |||
'ts-infobox-slider__nav ' + | |||
'ts-infobox-slider__next'; | |||
next.innerHTML = '›'; | |||
next.setAttribute( | |||
'aria-label', | |||
'次の画像' | |||
); | |||
slider.appendChild(prev); | |||
slider.appendChild(next); | |||
/* ----------------------------------------- | |||
ボタン状態 | |||
----------------------------------------- */ | |||
function updateButtons() { | |||
var max = | |||
track.scrollWidth - | |||
track.clientWidth; | |||
prev.disabled = | |||
track.scrollLeft <= 3; | |||
next.disabled = | |||
track.scrollLeft >= max - 3; | |||
} | |||
/* ----------------------------------------- | |||
1枚分移動 | |||
----------------------------------------- */ | |||
function move(direction) { | |||
track.scrollBy({ | |||
left: | |||
direction * | |||
track.clientWidth, | |||
behavior: 'smooth' | |||
}); | |||
} | |||
prev.addEventListener( | |||
'click', | |||
function () { | |||
move(-1); | |||
} | |||
); | |||
next.addEventListener( | |||
'click', | |||
function () { | |||
move(1); | |||
} | |||
); | |||
track.addEventListener( | |||
'scroll', | |||
function () { | |||
window.requestAnimationFrame( | |||
updateButtons | |||
); | |||
}, | |||
{ | |||
passive: true | |||
} | |||
); | |||
window.addEventListener( | |||
'resize', | |||
updateButtons | |||
); | |||
updateButtons(); | |||
}); | |||
}); | }); | ||
2026年9月2日 (水) 10:18時点における最新版
/* ここにある全ての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();
});
});
/* =========================================================
* Infobox 画像スライダー
* ========================================================= */
mw.hook('wikipage.content').add(function ($content) {
$content.find('.ts-infobox-slider').each(function () {
var slider = this;
/* 二重初期化を防止 */
if (slider.dataset.infoboxSliderReady === '1') {
return;
}
slider.dataset.infoboxSliderReady = '1';
var track =
slider.querySelector('.ts-infobox-slider__track');
if (!track) {
return;
}
var slides =
track.querySelectorAll('.ts-infobox-slider__slide');
if (!slides.length) {
return;
}
/*
* 1枚だけなら矢印を作らない
*/
if (slides.length === 1) {
slider.classList.add(
'ts-infobox-slider--single'
);
return;
}
/* -----------------------------------------
戻るボタン
----------------------------------------- */
var prev =
document.createElement('button');
prev.type = 'button';
prev.className =
'ts-infobox-slider__nav ' +
'ts-infobox-slider__prev';
prev.innerHTML = '‹';
prev.setAttribute(
'aria-label',
'前の画像'
);
/* -----------------------------------------
次へボタン
----------------------------------------- */
var next =
document.createElement('button');
next.type = 'button';
next.className =
'ts-infobox-slider__nav ' +
'ts-infobox-slider__next';
next.innerHTML = '›';
next.setAttribute(
'aria-label',
'次の画像'
);
slider.appendChild(prev);
slider.appendChild(next);
/* -----------------------------------------
ボタン状態
----------------------------------------- */
function updateButtons() {
var max =
track.scrollWidth -
track.clientWidth;
prev.disabled =
track.scrollLeft <= 3;
next.disabled =
track.scrollLeft >= max - 3;
}
/* -----------------------------------------
1枚分移動
----------------------------------------- */
function move(direction) {
track.scrollBy({
left:
direction *
track.clientWidth,
behavior: 'smooth'
});
}
prev.addEventListener(
'click',
function () {
move(-1);
}
);
next.addEventListener(
'click',
function () {
move(1);
}
);
track.addEventListener(
'scroll',
function () {
window.requestAnimationFrame(
updateButtons
);
},
{
passive: true
}
);
window.addEventListener(
'resize',
updateButtons
);
updateButtons();
});
});