如何解决如何将此 Javascript 滑块转换为 OOP 解决方案?
在解释问题之前,这里有一些上下文。学校希望我们仅使用 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);
}
}
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();
此代码不起作用,但我不明白为什么。
这里是我的问题:
免责声明:这个项目已经结束。我特意等到时限结束再问,因为不想用别人的代码来拿这门课的积分。
感谢您的帮助,对这么长的文字深表歉意。
解决方法
您的思考过程非常适合为此创建单个类对象。
第一个错误是在类的根目录中定义的所有内容都可以通过使用 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 和函数,以“说明”在哪个上下文中使用 var 或函数。 - 您不需要在开头声明三个变量
slideIndex
、slides
和dots
,因为这已经在构造函数中完成了。 - 内联事件侦听器不适用于该 OOP 结构。因此,您应该将它们添加到函数
setupSlider()
中。
因为使用容器类是setup函数中选择.prev
-和.next
-按钮最简单的方法,所以应该把它交给构造函数,例如:{{1 }}。如果您只是将构造函数 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,.dot:hover {
/* changes background-color */
}
q {
/* changes font-style */
}
.author {
/* changes color */
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。