[英]How to convert this Javascript slider to an OOP solution?
在解釋問題之前,這里有一點上下文。 學校希望我們從頭開始構建一個單頁 web 簡歷,僅使用 HTML/CSS、Javascript 和 JQuery。
對於那個項目,我有很多想法。 其中之一是使用報價 slider。 每 x 秒它滑到下一個報價。 所以我去尋找一些可行的東西,我找到了這個並對其進行了調整,使其看起來像:
slideIndex = 1; function plusSlides(n) { showSlides(slideIndex += n); } function currentSlide(n) { showSlides(slideIndex = n); } function showSlides(n) { var i; var slides = document.getElementsByClassName("slide"); var dots = document.getElementsByClassName("dot"); if (n > slides.length) { slideIndex = 1; } if (n < 1) { slideIndex = slides.length; } for (i = 0; i < slides.length; i++) { slides[i].style.display = "none"; } for (i = 0; i < dots.length; i++) { dots[i].className = dots[i].className.replace(" activeDot", ""); } slides[slideIndex - 1].style.display = "block"; dots[slideIndex - 1].className += " activeDot"; } $(document).ready(function() { showSlides(slideIndex); setInterval(() => { plusSlides(1); }, 5000); });
.sliderContainer { position: relative; background: #eee; /* Not useful here */ }.slide { display: none; padding: 30px; text-align: center; }.prev, .next { cursor: pointer; position: absolute; top: 50%; width: auto; margin-top: -30px; padding: 16px; color: #444; font-weight: bold; font-size: 20px; border-radius: 0 3px 3px 0; user-select: none; }.next { position: absolute; right: 0; border-radius: 3px 0 0 3px; }.prev:hover, .next:hover { /* Changes color and background color */ }.dotContainer { margin-bottom: 30px; text-align: center; padding: 20px; }.dot { cursor: pointer; height: 15px; width: 15px; margin: 0 20px; background-color: #444; /* still not useful but I let it */ border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; }.activeDot, .dot:hover { /* changes background-color */ } q { /* changes font-style */ }.author { /* changes color */ }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script> <div class="sliderContainer"> <div class="slide"> <q>A quote</q> <p class="author">The quote's author</p> </div> <div class="slide"> <q>Another quote</q> <p class="author">The quote's other author</p> </div> <;-- Left and Right buttons --> <a class="prev" onclick="plusSlides(-1)">❮</a> <a class="next" onclick="plusSlides(1)">❯</a> </div> <div class="dotContainer"> <span class="dot" onclick="currentSlide(1)"></span> <span class="dot" onclick="currentSlide(2)"></span> </div>
所以,這段代碼工作得很好。
但后來我想在其他地方添加另一個 slider。 這是一個數字 slider 而不是報價 slider,但這並沒有改變任何東西。 我確實在 HTML 中構建了它,並查看了它是如何工作的。 它不能正常工作,因為所有幻燈片都有相同的 class。 明顯地。
然后我嘗試將類從slide
更改為quoteSlide
和figureSlide
。 然后我意識到我需要更改與此相關的所有 JavaScript。 好吧,只有 2 個滑塊,沒關系。 我只是做了一個復制/粘貼並更改了函數的名稱和其他小東西,以獲得引用改編腳本和圖形改編腳本。
但后來,我意識到我總共需要七個滑塊。 而且我不會得到七次相同的腳本。 所以我想了想,我發現了一個有趣的想法。 在我學校的cursus中,我們學到了很多OOP(面向對象編程)。 但我們從未在 Javascript class 中談論它。 所以我對自己說,為什么不嘗試這樣做。
這不是最簡單的學習方法,但我設法得到了一些東西。 劇透:這件事沒有奏效。 但這里是:
class Slider {
slideIndex = 1;
slides;
dots;
constructor(index = 1, slides, dots) {
slideIndex = index;
slides = document.getElementsByClassName(slides);
dots = document.getElementsByClassName(dots);
}
plusSlides(n) {
showSlides(slideIndex += n);
}
currentSlide(n) {
showSlides(slideIndex = n);
}
showSlides(n) {
var i;
if (n > slides.length) { slideIndex = 1; }
if (n < 1) { slideIndex = slides.length; }
for(i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for(i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" activeDot", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " activeDot";
}
setupSlider() {
showSlides(slideIndex);
// Sliding automation
setInterval(() => {
plusSlides(1);
console.log(this.slideIndex);
}, 5000);
}
}
這是主 JS 文件中的代碼:
let quoteSlider = new Slider(1, ".quoteSlide", ".quoteDot");
let lectureSlider = new Slider(1, ".lectureSlide", ".lectureDot");
let gameSlider = new Slider(1, ".gameSlide", ".gameDot");
let softwareSlider = new Slider(1, ".softwareSlide", ".softwareDot");
let roboticSlider = new Slider(1, ".roboticSlide", ".roboticDot");
let teachingSlider = new Slider(1, ".teachingSlide", ".teachingDot");
let streamingSlider = new Slider(1, ".streamingSlide", ".streamingDot");
quoteSlider.setupSlider();
lectureSlider.setupSlider();
gameSlider.setupSlider();
softwareSlider.setupSlider();
roboticSlider.setupSlider();
teachingSlider.setupSlider();
streamingSlider.setupSlider();
這段代碼不起作用,但我不明白為什么。
所以這是我的問題:
免責聲明:這個項目已經結束。 我故意等到時限結束才問,因為我不想使用其他人的代碼來獲得這個 class 的積分。
謝謝你的幫助,很抱歉這么長的文字。
您的思考過程非常適合為此制作單個 class object。
第一個錯誤是在 class 的根目錄中定義的所有內容都可以通過使用this.
前綴,但是您嘗試僅通過其名稱訪問它,奇怪的是,除了構造函數之外,您正確使用它的唯一地方是console.log(this.slideIndex)
沒有辦法停止自動幻燈片 - 這可以改進。 此外,在某些情況下,最好通過 javascript 提供幻燈片內容,而不是硬編碼到 HTML 中,而是使用 HTML 作為模板。
class Slider { slideIndex = 1; slides; dots; constructor(index = 1, sel) { this.slideIndex = index; const container = document.querySelector(sel); this.slides = container.querySelectorAll(".slide"); const dots = container.querySelector(".dotContainer"); dots.innerHTML = ""; this.dots = []; for(let i = 0; i < this.slides.length; i++) { const dot = document.createElement("span"); dot.className = "dot"; dot.addEventListener("click", e => this.currentSlide(i + 1)); dots.appendChild(dot); this.dots[i] = dot; } const nav = container.querySelector(".nav"); nav.innerHTML = ""; const prev = document.createElement("a"); prev.className = "prev"; prev.addEventListener("click", e => this.plusSlides(-1)); prev.innerHTML = "❮"; nav.appendChild(prev); const next = document.createElement("a"); next.className = "next"; next.addEventListener("click", e => this.plusSlides(-1)); next.innerHTML = "❯"; nav.appendChild(next); } plusSlides(n) { this.showSlides(this.slideIndex += n); } currentSlide(n) { this.showSlides(this.slideIndex = n); } showSlides(n) { var i; if (n > this.slides.length) { this.slideIndex = 1; } if (n < 1) { this.slideIndex = this.slides.length; } for (i = 0; i < this.slides.length; i++) { this.slides[i].style.display = i == this.slideIndex - 1? "block": "none"; } for (i = 0; i < this.dots.length; i++) { this.dots[i].classList.toggle("activeDot", i == this.slideIndex-1); } } timer = null; stopSlider() { clearInterval(this.timer); } setupSlider(speed) { this.showSlides(this.slideIndex); if (speed === undefined) speed = 5000; // Sliding automation clearInterval(this.timer); this.timer = setInterval(() => { this.plusSlides(1); console.log(this.slideIndex); }, speed); } } let quoteSlider = new Slider(1, ".quoteSlide"); quoteSlider.setupSlider(1000); /* let lectureSlider = new Slider(1, ".lectureSlide", ".lectureDot"); let gameSlider = new Slider(1, ".gameSlide", ".gameDot"); let softwareSlider = new Slider(1, ".softwareSlide", ".softwareDot"); let roboticSlider = new Slider(1, ".roboticSlide", ".roboticDot"); let teachingSlider = new Slider(1, ".teachingSlide", ".teachingDot"); let streamingSlider = new Slider(1, ".streamingSlide", ".streamingDot"); lectureSlider.setupSlider(); gameSlider.setupSlider(); softwareSlider.setupSlider(); roboticSlider.setupSlider(); teachingSlider.setupSlider(); streamingSlider.setupSlider(); */
.sliderContainer { position: relative; background: #eee; /* Not useful here */ }.slide { display: none; padding: 30px; text-align: center; }.prev, .next { cursor: pointer; position: absolute; top: 50%; width: auto; margin-top: -30px; padding: 16px; color: #444; font-weight: bold; font-size: 20px; border-radius: 0 3px 3px 0; user-select: none; }.next { position: absolute; right: 0; border-radius: 3px 0 0 3px; }.prev:hover, .next:hover { /* Changes color and background color */ }.dotContainer { margin-bottom: 30px; text-align: center; padding: 20px; }.dot { cursor: pointer; height: 15px; width: 15px; margin: 0 20px; background-color: #444; /* still not useful but I let it */ border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; }.activeDot, .dot:hover { /* changes background-color */ } q { /* changes font-style */ }.author { /* changes color */ }
<!-- Unrelated content --> <div class="quoteSlide"> <div class="sliderContainer"> <div class="slide"> <q>A quote</q> <p class="author">The quote's author</p> </div> <div class="slide"> <q>Another quote</q> <p class="author">The quote's author</p> </div> <!-- Left and Right buttons --> <div class="nav"> </div> </div> <div class="dotContainer"> </div> </div>
你的方法很好,我只發現了三個問題:
this.
對於“說”,在上下文中使用 var 或 function。slideIndex
、 slides
和dots
,因為這已經在構造函數中完成了。setupSlider()
中。 因為容器 class 的使用是在設置 function 中選擇.prev
和.next
按鈕的最簡單方法,所以您應該將其提供給構造函數,例如: let quoteSlider = new Slider(1, ".quotes");
. 如果您只是將構造函數'.slide'
或'.dot'
添加到選擇器中的容器 class 中,則可以省略特定的類,例如.quoteSlide
或.quoteDot
。 當然,您必須將該容器 class 給容器,例如: class="sliderContainer quotes"
和class="dotContainer quotes"
。
工作示例:
class Slider { constructor(index = 1, container) { this.slideIndex = index; this.container = container; this.slides = document.querySelectorAll(container + ".slide"); this.dots = document.querySelectorAll(container + ".dot"); } plusSlides(n) { this.showSlides(this.slideIndex += n); } currentSlide(n) { this.showSlides(this.slideIndex = n); } showSlides(n) { var i; if (n > this.slides.length) { this.slideIndex = 1; } if (n < 1) { this.slideIndex = this.slides.length; } for (i = 0; i < this.slides.length; i++) { this.slides[i].style.display = "none"; } for (i = 0; i < this.dots.length; i++) { this.dots[i].className = this.dots[i].className.replace(" activeDot", ""); } this.slides[this.slideIndex - 1].style.display = "block"; this.dots[this.slideIndex - 1].className += " activeDot"; } setupSlider() { document.querySelector(this.container + ".prev").addEventListener("click", e => this.plusSlides(-1) ); document.querySelector(this.container + ".next").addEventListener("click", e => this.plusSlides(1) ); for (let i = 0; i < this.dots.length; i++) { this.dots[i].addEventListener("click", e => this.currentSlide(i + 1)); } this.showSlides(this.slideIndex); // Sliding automation setInterval(() => { this.plusSlides(1); }, 5000); } } $(document).ready(function() { let quoteSlider = new Slider(1, ".quotes"); let lectureSlider = new Slider(1, ".lectures"); let gameSlider = new Slider(1, ".games"); let softwareSlider = new Slider(1, ".software"); let roboticSlider = new Slider(1, ".robotics"); let teachingSlider = new Slider(1, ".teachings"); let streamingSlider = new Slider(1, ".streaming"); quoteSlider.setupSlider(); lectureSlider.setupSlider(); gameSlider.setupSlider(); softwareSlider.setupSlider(); roboticSlider.setupSlider(); teachingSlider.setupSlider(); streamingSlider.setupSlider(); });
.sliderContainer { position: relative; background: #eee; /* Not useful here */ }.slide { display: none; padding: 30px; text-align: center; }.prev, .next { cursor: pointer; position: absolute; top: 50%; width: auto; margin-top: -30px; padding: 16px; color: #444; font-weight: bold; font-size: 20px; border-radius: 0 3px 3px 0; user-select: none; }.next { position: absolute; right: 0; border-radius: 3px 0 0 3px; }.prev:hover, .next:hover { /* Changes color and background color */ }.dotContainer { margin-bottom: 30px; text-align: center; padding: 20px; }.dot { cursor: pointer; height: 15px; width: 15px; margin: 0 20px; background-color: #444; /* still not useful but I let it */ border-radius: 50%; display: inline-block; transition: background-color 0.6s ease; }.activeDot, .dot:hover { /* changes background-color */ } q { /* changes font-style */ }.author { /* changes color */ }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-color/2.1.2/jquery.color.min.js"></script> <div class="sliderContainer quotes"> <div class="slide"> <q>A quote</q> <p class="author">The quote's author</p> </div> <div class="slide"> <q>Another quote</q> <p class="author">The quote's other author</p> </div> <;-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer quotes"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer lectures"> <div class="slide"> <q>A lecture</q> <p class="author">The lecture's author</p> </div> <div class="slide"> <q>Another lecture</q> <p class="author">The lecture's other author</p> </div> <;-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer lectures"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer games"> <div class="slide"> <q>A game</q> <p class="author">The game's author</p> </div> <div class="slide"> <q>Another game</q> <p class="author">The game's other author</p> </div> <;-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer games"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer software"> <div class="slide"> <q>A software</q> <p class="author">The software's author</p> </div> <div class="slide"> <q>Another software</q> <p class="author">The software's other author</p> </div> <;-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer software"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer robotics"> <div class="slide"> <q>A robotic</q> <p class="author">The robotic's author</p> </div> <div class="slide"> <q>Another robotic</q> <p class="author">The robotic's other author</p> </div> <;-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer robotics"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer teachings"> <div class="slide"> <q>A teaching</q> <p class="author">The teaching's author</p> </div> <div class="slide"> <q>Another teaching</q> <p class="author">The teaching's other author</p> </div> <!-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer teachings"> <span class="dot"></span> <span class="dot"></span> </div> <div class="sliderContainer streaming"> <div class="slide"> <q>A streaming</q> <p class="author">The streaming's author</p> </div> <div class="slide"> <q>Another streaming</q> <p class="author">The streaming's other author</p> </div> <!-- Left and Right buttons --> <a class="prev">❮</a> <a class="next">❯</a> </div> <div class="dotContainer streaming"> <span class="dot"></span> <span class="dot"></span> </div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.