こんにちは、コンスキです。
今回は、パソコンように作ったスライダーの画像が数秒おきに自動で切り替わるように設定してみたいと思います。
JavaScript
数秒おきに切り替わるようにするために、これまでに書いてきた「main.js」というjsファイルを下のように変更しました。
今回コードを追加したことで、以前と大きく変わった部分は背景の色が濃くなっています。
大きく変わっていなくても、以前と比べると変化している部分があるため、ファイル全体のコードを載せました。
// 画面幅の範囲を設定
let windowWidth = window.innerWidth;
let tabletBreakPoint = 999;
// vwをpxに変換する関数
function vw(v) {
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
return (v * w) / 100;
}
// // スライダー
// 要素を取得する
let imgSlider = document.getElementById('img_slider_item_container');
let imageArray = imgSlider.getElementsByTagName('img');
let liSlider = document.getElementById('blog_text_list');
let textArray = liSlider.getElementsByTagName('li');
let nextButton = document.getElementById('down_arrow');
let prevButton = document.getElementById('up_arrow');
let categoryArray = document.getElementsByClassName('blog_category')
let pagination = document.getElementById('blog_content_pagination');
let paginationCircle = pagination.getElementsByTagName('svg');
// 表示されているスライダー画像のインデックスと一つ前のスライダー画像のインデックスを設定
let activeElementIndex = 0;
let prevElementIndex = 0;
//画面幅によって分岐
if(windowWidth > tabletBreakPoint) {
//表示しているブログのカテゴリーを強調すして、一つ前に表示されていたのカテゴリーをもとに戻す関数
function fontSwitching() {
categoryArray[activeElementIndex].classList.add('emphasize');
categoryArray[prevElementIndex].classList.remove('emphasize');
}
// 表示されている画像以外の位置を「top: 70px;」にリセットする関数
function imgPositionReset() {
Object.keys(imageArray).filter(function(element) {
return element != activeElementIndex;
}).forEach(function(key) {
imageArray[key].style.top = '70px';
})
}
// 1番目のスライド画像の表示と1番目のカテゴリーの強調
imageArray[activeElementIndex].style.opacity = '1';
imageArray[activeElementIndex].style.top = '0';
categoryArray[activeElementIndex].classList.add('emphasize');
// 1番目のブログタイトルとブログの内容の表示
textArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.top = '0';
// 次の要素に切り替える関数
function nextElement(){
imageArray[activeElementIndex].style.opacity = '0';
textArray[activeElementIndex].style.opacity = '0';
setTimeout(function() {
imageArray[activeElementIndex].style.top = '-70px';
textArray[activeElementIndex].style.top = '-70px';
prevElementIndex = activeElementIndex;
if(activeElementIndex >= imageArray.length - 1){
activeElementIndex = 0;
} else {
activeElementIndex++;
}
setTimeout(function() {
imageArray[activeElementIndex].style.top = '0';
textArray[activeElementIndex].style.top = '0';
setTimeout(function() {
imageArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.opacity = '1';
imgPositionReset();
}, 100)
}, 500);
fontSwitching();
}, 100)
}
// 前の要素に切り替える関数
function previousElement(){
imageArray[activeElementIndex].style.opacity = '0';
textArray[activeElementIndex].style.opacity = '0';
setTimeout(function() {
imageArray[activeElementIndex].style.top = '-70px';
textArray[activeElementIndex].style.top = '-70px';
if(activeElementIndex <= 0){
activeElementIndex = imageArray.length - 1;
} else {
activeElementIndex--;
}
setTimeout(function() {
imageArray[activeElementIndex].style.top = '0';
textArray[activeElementIndex].style.top = '0';
setTimeout(function() {
imageArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.opacity = '1';
imgPositionReset();
}, 100)
}, 500);
fontSwitching();
}, 100)
}
// 下矢印をクリックされたら次の要素に切り替える
nextButton.addEventListener('click', function() {
nextElement();
});
// 上矢印をクリックされたら前の要素に切り替える
prevButton.addEventListener('click', function() {
previousElement();
});
} else {
// 全てのスライダー\画像の位置を「left: 193.791vw;」に設定
Object.keys(imageArray).forEach(function(key) {
imageArray[key].style.left = vw(193.791) + 'px';
});
// 表示されているスライダー画像以外の位置を「left: 193.791vw;」にリセットする関数
function imgPositionReset() {
Object.keys(imageArray).filter(function(element) {
return element != activeElementIndex
}).forEach(function(key) {
setTimeout(function() {
imageArray[key].style.left = vw(193.791) + 'px';
}, 150)
})
}
// 1番目のスライダー画像の表示
imageArray[activeElementIndex].style.opacity = '1';
imageArray[activeElementIndex].style.left = '0';
// 1番目のブログタイトルとブログの内容の表示
let textArray = liSlider.getElementsByTagName('li');
textArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.left = '0';
// ページネーションの1番目(1番左)の丸を黒くする
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#000000';
// 1番目のスライダー画像に切り替える
function firstElement() {
imageArray[activeElementIndex].style.opacity = '0';
textArray[activeElementIndex].style.opacity = '0';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#ffffff';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '-' + vw(93.791) + 'px';
activeElementIndex = 0;
imageArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.opacity = '1';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#000000';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '0' ;
imgPositionReset();
}, 100);
}, 100);
}
// 2番目のスライダー画像に切り替える
function secondElement() {
imageArray[activeElementIndex].style.opacity = '0';
textArray[activeElementIndex].style.opacity = '0';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#ffffff';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '-' + vw(93.791) + 'px';
activeElementIndex = 1;
imageArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.opacity = '1';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#000000';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '0' ;
imgPositionReset();
}, 100);
}, 100);
}
// 3番目のスライダー画像に切り替える
function thirdElement() {
imageArray[activeElementIndex].style.opacity = '0';
textArray[activeElementIndex].style.opacity = '0';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#ffffff';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '-' + vw(93.791) + 'px';
activeElementIndex = 2;
imageArray[activeElementIndex].style.opacity = '1';
textArray[activeElementIndex].style.opacity = '1';
paginationCircle[activeElementIndex].getElementsByTagName('circle')[0].style.fill = '#000000';
setTimeout(function() {
imageArray[activeElementIndex].style.left = '0' ;
imgPositionReset();
}, 100);
}, 100);
}
// ページネーション1番目(左)の丸をクリックされたら1番目の要素に切り替える
paginationCircle[0].addEventListener('click', function() {
firstElement();
});
// ページネーション2番目(真ん中)の丸をクリックされたら2番目の要素に切り替える
paginationCircle[1].addEventListener('click', function() {
secondElement();
});
// ページネーション3番目(真ん中)の丸をクリックされたら3番目の要素に切り替える
paginationCircle[2].addEventListener('click', function() {
thirdElement();
});
}
// ハンバーガーメニュー
// 要素の取得
let hamburgerButton = document.getElementById('hamburger_button');
let hamburgerMenu = document.getElementById('hamburger_menu');
let hamburgerLine = document.getElementsByClassName('hamburger_line');
//ハンバーガメニュー状態
let isOpen = false;
//ハンバーガーメニューを画面の表示と非表示
function showAndHide() {
if(!isOpen) {
hamburgerMenu.style.top = '64px';
} else {
hamburgerMenu.style.top = '-1000px';
}
}
//ハンバーガーメニューのアイコンの変形
function changeIcon() {
if(!isOpen) {
hamburgerLine[0].style.marginTop = '8px';
hamburgerLine[1].style.marginBottom = '8px';
setTimeout(function() {
hamburgerLine[0].style.transform = 'rotate(45deg)';
hamburgerLine[1].style.transform = 'rotate(-45deg)';
}, 200);
} else {
hamburgerLine[0].style.transform = 'rotate(0deg)';
hamburgerLine[1].style.transform = 'rotate(0deg)';
setTimeout(function() {
hamburgerLine[0].style.marginTop = '0';
hamburgerLine[1].style.marginBottom = '0';
}, 200);
}
}
hamburgerButton.addEventListener('click', function() {
showAndHide();
changeIcon();
isOpen = !isOpen;
});
//インターバルを開始
var intervalId = setInterval(function () {
nextElement();
}, 10000);
今回重要になってくるのは最後の3行です。
この部分では、10秒おきにスライダー画像を切り替えるnextElementという関数を実行するために「setInterval」という名前の関数を使っています。
コードを書き終わった後に動作確認を行いました。
10秒おきの設定だとスライダーが切り替わるまでかなり待たないといけないため、動作確認では3秒に設定しています。
自動でスライダーが切り替わっている途中に、手動でスライダーの画像を切り替えてみたらどうなるでしょうか?
下方向へ手動で切り替えた時はなんとか動作しますが、上方向へ切り替えた時はブログ画像や左側にある強調されている文字2つ同時にされてしまいます。
ここは修正が必要みたいです。
コメント