動画の周りに黒い線が入る
画面をスクショするときには黒い線が消える
→画面が小数点以下のpx数をとっていて、勝手に黒い線を表示してしまっている可能性がある
・動画の比率が原因であることが多いが、それでも改善されなかった
・そのため、動画のafter要素に1pxの色付きの線を重ねて、黒い線が目立たないように対応した。
video要素にafter要素は適用したいがうまくいかない
video要素にはafter要素は使用できない
動画の読み込みを検知して処理を開始する
canplaythrough イベントを使用することで、動画の読み込みが完了したことを検知します。
body.no-scroll {
overflow: hidden;
}
<script>
// 初期状態でスクロールを無効にする
document.body.classList.add('no-scroll');
// 動画要素を取得
var video = document.getElementById('myVideo');
// 動画が完全に読み込まれたときの処理
video.addEventListener('canplaythrough', function() {
// スクロールを有効にする
document.body.classList.remove('no-scroll');
});
</script>
動画がある箇所に入ったときに動画を再生する
<script>
// 動画要素を取得
const video = document.getElementById('myVideo');
// IntersectionObserverのオプション
const options = {
root: null, // ビューポートを基準にする
rootMargin: '0px', // 余白なし
threshold: 0.5 // 要素が50%表示されたら反応する
};
// コールバック関数
const callback = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 要素がビューポート内に入ったら動画を再生
video.play();
} else {
// 要素がビューポート外に出たら動画を停止
video.pause();
}
});
};
// IntersectionObserverのインスタンスを作成
const observer = new IntersectionObserver(callback, options);
// 動画要素を監視
observer.observe(video);
</script>
連続したスクロールだと完了の判定がズレる
// デバウンス用の関数
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
// スクロールが完了したときに呼び出す処理
function onScrollComplete() {
console.log('スクロールが完了しました。次の処理を実行');
}
// スクロールイベントをデバウンスして処理
window.addEventListener('scroll', debounce(function() {
if (window.scrollY >= 1000) { // 任意の条件でスクロール位置を確認
onScrollComplete();
}
}, 200)); // 200msの待機時間(適宜調整)
scrollToでページの位置を操作してもその通りに動かない
ブラウザのスクロール復元機能が問題になっている場合は、以下のコードを追加して、ブラウザがスクロール位置を復元しないようにするとうまくいく。
if ('scrollRestoration' in history) {
history.scrollRestoration = 'manual';
}
window.addEventListener('load', function () {
window.scrollTo(0, 0);
});
スクロールが確実に終わったら処理を開始するようにしたい
setTimeoutを使うことでスクロール停止を待つことができる理由は、スクロールイベントが連続して発生する性質にあります。setTimeoutの遅延を使って、スクロールが続いていない(スクロールイベントが一定時間発生しない)状態を検出するためにタイミングを調整しています。
let isScrolling; // タイマー用の変数
let flag = false; // フラグの初期状態
window.addEventListener('scroll', function () {
// スクロール中は flag を false にする
flag = false;
// 前回のタイマーをクリア
clearTimeout(isScrolling);
// スクロール停止を待つ (300ms程度)
isScrolling = setTimeout(function() {
// スクロール停止後にフラグを true にする
flag = true;
console.log('スクロールが完了しました: flag =', flag);
// スクロール距離が 100 を超え、かつ flag が true の場合に処理を実行
if (window.scrollY > 100 && flag) {
// 条件を満たしたときに実行する処理
console.log('スクロールが100を超え、かつスクロールが完了しました');
executeAfterScroll();
}
}, 300); // スクロールが終わったと見なす時間(ms)
});
function executeAfterScroll() {
// スクロール完了後の処理をここに書く
console.log('スクロール完了後の処理を実行');
}
scrollbar-gutter:stableとoverflow-y:hiddenを用いて、overflow-y:hiddenによるスクロールバー非表示の対策をしている。position:fixedを与えたナビゲーションをright:0で固定しているが、scrollbar-gutter:stableの下に重なって見えなくなってしまった。
ブラウザの再ロードをすることでブラウザの描画が更新される。表示の更新はdocumnt.documentElement.offsetWidthを実行。
さらに、以下のコードでナビゲーションの位置を調節することで対応する。
.nav {
position: fixed;
top: 0;
right: calc(var(--scrollbar-width, 0px));
}
function getScrollbarWidth() {
return window.innerWidth - document.documentElement.clientWidth;
}
document.documentElement.style.setProperty('--scrollbar-width', `${getScrollbarWidth()}px`);