簡體   English   中英

如何將此 Javascript slider 轉換為 OOP 解決方案?

[英]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)">&#10094;</a> <a class="next" onclick="plusSlides(1)">&#10095;</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更改為quoteSlidefigureSlide 然后我意識到我需要更改與此相關的所有 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();

這段代碼不起作用,但我不明白為什么。

所以這是我的問題:

  • 我在思考過程中犯了錯誤嗎? 哪一個?
  • 我在所有這些 JS 的東西中哪里犯了錯誤?
  • 你會給知道上下文的老師的解決方案是什么?
  • 在全球范圍內有什么可以做得更好的嗎?

免責聲明:這個項目已經結束。 我故意等到時限結束才問,因為我不想使用其他人的代碼來獲得這個 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 = "&#10094;"; nav.appendChild(prev); const next = document.createElement("a"); next.className = "next"; next.addEventListener("click", e => this.plusSlides(-1)); next.innerHTML = "&#10095;"; 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>

你的方法很好,我只發現了三個問題:

  • 您必須在其中調用 class 的變量和函數this. 對於“說”,在上下文中使用 var 或 function。
  • 您不需要在開頭聲明三個變量slideIndexslidesdots ,因為這已經在構造函數中完成了。
  • 內聯事件偵聽器不適用於 OOP 結構。 因此,您應該將它們添加到 function 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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</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">&#10094;</a> <a class="next">&#10095;</a> </div> <div class="dotContainer streaming"> <span class="dot"></span> <span class="dot"></span> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM