[英]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.