如何将此 Javascript 滑块转换为 OOP 解决方案?
Posted
技术标签:
【中文标题】如何将此 Javascript 滑块转换为 OOP 解决方案?【英文标题】:How to convert this Javascript slider to an OOP solution? 【发布时间】:2021-08-14 11:56:30 【问题描述】:在解释问题之前,这里有一点上下文。学校希望我们只使用 html/CSS、javascript 和 JQuery 从头开始构建单页网络简历。
对于那个项目,我有很多想法。其中之一是使用报价滑块。每 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>
所以,这段代码运行良好。
但后来我想在其他地方添加另一个滑块。这是一个数字滑块而不是报价滑块,但这并没有改变任何东西。 我确实在 HTML 中构建了它,并查看了它是如何工作的。 而且它不能正常工作,因为所有幻灯片都有相同的类。很明显。
然后我尝试将课程从slide
更改为quoteSlide
和figureSlide
。然后我意识到我需要更改所有与此相关的 JavaScript。
好吧,只有 2 个滑块,没关系。我只是复制/粘贴并更改了函数的名称和其他小东西,以获得引用改编脚本和图形改编脚本。
但后来,我意识到我总共需要 七个 滑块。而且我不会得到七次相同的脚本。所以我想了想,我发现了一个有趣的想法。 在我的学校课程中,我们学习了很多 OOP(面向对象编程)。但我们从未在 Javascript 课程中讨论过它。 所以我对自己说,为什么不尝试这样做呢。
这不是最简单的学习方法,但我设法得到了一些东西。剧透:这东西没用。但这里是:
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 内容中哪里出错了? 如果您知道上下文,您会为老师提供什么解决方案? 在全球范围内有什么可以做得更好的事情吗?免责声明:这个项目已经结束。我故意等到时限结束才问,因为我不想用别人的代码来获得这门课的积分。
感谢您的帮助,很抱歉这么长的文字。
【问题讨论】:
【参考方案1】:您的思维过程很适合为此制作单个类对象。
第一个错误是可以使用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.
不好我尝试使用它,但它在我编写代码的方式上也不起作用。你看到的那个是我忘记删除的那个。我需要查看你的代码,看看它是如何完成的,然后我会给你一个反馈
是的,我稍后会添加 cmets,现在没时间了。【参考方案2】:
你的方法很好,我只发现了三个问题:
您必须使用this.
在其中调用该类的变量和函数,以“说明”在哪个上下文中使用变量或函数。
您不需要在开头声明三个变量slideIndex
、slides
和dots
,因为这已经在构造函数中完成了。
内联事件侦听器不适用于该 OOP 结构。因此,您应该将它们添加到函数setupSlider()
。
因为容器类的使用是在设置函数中选择.prev
-和.next
-按钮最简单的方法,所以你应该把它交给构造函数,例如:let quoteSlider = new Slider(1, ".quotes");
。您可以省略特定的类,如.quoteSlide
或.quoteDot
,如果您只需将构造函数' .slide'
或' .dot'
添加到选择器中的容器类。当然,您必须将容器类赋予容器,例如: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>
【讨论】:
以上是关于如何将此 Javascript 滑块转换为 OOP 解决方案?的主要内容,如果未能解决你的问题,请参考以下文章
如何在javascript中将嵌套对象转换为对象数组? [关闭]
有啥方法可以将此字符串:“Coordenação”转换为:javascript/jquery 中的“Coordenação”?
如何在 JavaScript 中将时间戳转换为 MySQL DateTime?