I have created a javascript class TkpSlider being inspired from this w3schools page. (JSFiddle)
var TkpSlider = function (args) {
args= args|| {};
};
var mainSwiper = new TkpSlider();
I have extended this to add some swipe ability being inspired from this page so that I can the slider works on user swipe. (JSFiddle)
var TkpSwiper = function (args) {
TkpSlider.call(this, args);
};
TkpSwiper.prototype = Object.create(TkpSlider.prototype);
var mainSwiper = new TkpSwiper();
I separated the code so I don't get confused later from the base code and if any additional function. But with OOP I have to extend by creating a new name for it TkpSwiper, But I want to find another way to use the same name TkpSlider.
I saw this article and tried to use prototype to extend TkpSlider in this JSFiddle (Snippet below). The problem is I can't access the public methods of the base class from child class. The sample javascript in the blog I tested working though, I must be missing something with my code. Could anyone shed some insight? Thanks.
var TkpSlider = function (args) {
args= args|| {};
//private variable
var btnPrev = args.btnPrev || "tkp-slide-btn-prev";//class for previous button (default: "tkp-slide-btn-prev")
var btnNext = args.btnNext || "tkp-slide-btn-next";//class for next button (default: "tkp-slide-btn-next")
var itemClass = args.itemClass || "tkp-slide-item"; //each item container class to slide (default: "tkp-slide-item")
var isAutoSlide = args.isAutoSlide || false;//set auto slide (default: false)
var autoSlideTimer = args.autoSlideTimer || 2000;//set auto slide timer when isAutoSlide is true(default: 2000)
var hideBtnNav = args.hideBtnNav || false; //hide button navigation(default: false)
var isRandom = args.isRandom || false; //whether next or previous slide should be random index
var slideIndex = args.startIndex || 0; //start slide index number (zero based, index 0 = slide number 1, default :0)
var itemNodes = document.getElementsByClassName(itemClass);
var itemLength = itemNodes.length;
var autoSlideInterval;
//public variable
this.testParentVar = "parent var";
//init function
init();
function init() {
if (itemLength > 0) {
showSlide();
bindEvent();
isAutoSlide ? setAutoSlide() : "";
hideBtnNav ? setHideBtnNav() : "";
} else {
throw "Cannot find slider item class";
}
}
//private function
function showSlide() {
if (slideIndex >= itemLength) { slideIndex = 0; }
if (slideIndex < 0) { slideIndex = (itemLength - 1); }
for (var i = 0; i < itemLength; i++) {
itemNodes[i].style.display = "none";
}
itemNodes[slideIndex].style.display = "block";
}
function nextPrevSlide(n) {
slideIndex += n;
showSlide();
}
function bindEvent() {
var btnPrevNode = document.getElementsByClassName(btnPrev);
if (btnPrevNode.length > 0) {
btnPrevNode[0].addEventListener("click", function () {
if (isRandom) {
setRandomSlideIndex();
} else {
nextPrevSlide(-1);
}
if (isAutoSlide) {
clearInterval(autoSlideInterval);
setAutoSlide();
}
});
} else {
throw "Cannot find button previous navigation";
}
var btnNextNode = document.getElementsByClassName(btnNext);
if (btnNextNode.length > 0) {
btnNextNode[0].addEventListener("click", function () {
if (isRandom) {
setRandomSlideIndex();
} else {
nextPrevSlide(1);
}
if (isAutoSlide) {
clearInterval(autoSlideInterval);
setAutoSlide();
}
});
} else {
throw "Cannot find button next navigation";
}
}
function setAutoSlide() {
autoSlideInterval = setInterval(function () {
if (isRandom) {
setRandomSlideIndex();
} else {
nextPrevSlide(1);
}
}, autoSlideTimer);
}
function setHideBtnNav() {
document.getElementsByClassName(btnPrev)[0].style.display = "none";
document.getElementsByClassName(btnNext)[0].style.display = "none";
}
function setRandomSlideIndex() {
var randomIndex = Math.floor(Math.random() * itemLength);
if (randomIndex == slideIndex) {
setRandomSlideIndex();
} else {
slideIndex = randomIndex;
showSlide();
}
}
//public function
this.nextPrevSlide = function (n) {
nextPrevSlide(n);
//console.log("nextPrevSlide");
};
//getter setter
this.setItemClass = function (prm) {
itemClass = prm;
};
this.getItemClass = function () {
return itemClass;
};
};
//Adding touch swiper
TkpSlider.prototype = function () {
var self = this;
var touchStartCoords = { 'x': -1, 'y': -1 }, // X and Y coordinates on mousedown or touchstart events.
touchEndCoords = { 'x': -1, 'y': -1 },// X and Y coordinates on mouseup or touchend events.
direction = 'undefined',// Swipe direction
minDistanceXAxis = 30,// Min distance on mousemove or touchmove on the X axis
maxDistanceYAxis = 30,// Max distance on mousemove or touchmove on the Y axis
maxAllowedTime = 1000,// Max allowed time between swipeStart and swipeEnd
startTime = 0,// Time on swipeStart
elapsedTime = 0,// Elapsed time between swipeStart and swipeEnd
//targetElement = document.getElementById('el'), // Element to delegate
targetElements = self.getItemClass()
;
init();
function init() {
addMultipleListeners(targetElements, 'mousedown touchstart', swipeStart);
addMultipleListeners(targetElements, 'mousemove touchmove', swipeMove);
addMultipleListeners(targetElements, 'mouseup touchend', swipeEnd);
}
function swipeStart(e) {
e = e ? e : window.event;
e = ('changedTouches' in e) ? e.changedTouches[0] : e;
touchStartCoords = { 'x': e.pageX, 'y': e.pageY };
startTime = new Date().getTime();
//targetElement.textContent = " ";
}
function swipeMove(e) {
e = e ? e : window.event;
e.preventDefault();
}
function swipeEnd(e) {
e = e ? e : window.event;
e = ('changedTouches' in e) ? e.changedTouches[0] : e;
touchEndCoords = { 'x': e.pageX - touchStartCoords.x, 'y': e.pageY - touchStartCoords.y };
elapsedTime = new Date().getTime() - startTime;
if (elapsedTime <= maxAllowedTime) {
if (Math.abs(touchEndCoords.x) >= minDistanceXAxis && Math.abs(touchEndCoords.y) <= maxDistanceYAxis) {
direction = (touchEndCoords.x < 0) ? 'left' : 'right';
switch (direction) {
case 'left':
//targetElement.textContent = "Left swipe detected";
console.log("swipe left");
self.nextPrevSlide(1);
break;
case 'right':
// targetElement.textContent = "Right swipe detected";
console.log("swipe right");
self.nextPrevSlide(-1);
break;
}
}
}
}
function addMultipleListeners(el, s, fn) {
var evts = s.split(' ');
var elLength = el.length;
for (var i = 0, iLen = evts.length; i < iLen; i++) {
if (elLength > 1) {
for (var j = 0; j < elLength; j++) {
el[j].addEventListener(evts[i], fn, false);
}
} else {
el.addEventListener(evts[i], fn, false);
}
}
}
}();
var mainSwiper = new TkpSlider();
.tkp-slide {
width: 100%;
position: relative; }
.tkp-slide .tkp-slide-item:not(:first-child) {
display: none; }
.tkp-slide .tkp-slide-item img {
width: 100%; }
.tkp-slide .tkp-slide-btn {
color: #fff !important;
background-color: #000 !important;
border: none;
display: inline-block;
outline: 0;
padding: 8px 16px;
vertical-align: middle;
overflow: hidden;
text-decoration: none;
text-align: center;
cursor: pointer;
white-space: nowrap;
opacity: 0.7; }
.tkp-slide .tkp-slide-btn:hover {
background-color: #333 !important; }
.tkp-slide .tkp-slide-btn-prev {
position: absolute;
top: 50%;
left: 0%;
transform: translate(0%, -50%);
-webkit-transform: translate(0%, -50%);
-ms-transform: translate(0%, -50%); }
.tkp-slide .tkp-slide-btn-next {
position: absolute;
top: 50%;
right: 0%;
transform: translate(0%, -50%);
-ms-transform: translate(0%, -50%); }
<section class="main-slide">
<div class="tkp-slide tkp-slide--container">
<div class="tkp-slide-item">
<a href="javascript:void(0)">
<img src="https://dummyimage.com/400x200/f2d9f2/080708&text=1" alt="Slide 1" />
</a>
</div>
<div class="tkp-slide-item">
<a href="javascript:void(0)">
<img src="https://dummyimage.com/400x200/f2d9f2/080708&text=2" alt="Slide 2" />
</a>
</div>
<div class="tkp-slide-item">
<a href="javascript:void(0)">
<img src="https://dummyimage.com/400x200/f2d9f2/080708&text=3" alt="Slide 3" />
</a>
</div>
<div class="tkp-slide-item">
<a href="javascript:void(0)">
<img src="https://dummyimage.com/400x200/f2d9f2/080708&text=4" alt="Slide 4" />
</a>
</div>
<div class="tkp-slide-item">
<a href="javascript:void(0)">
<img src="https://dummyimage.com/400x200/f2d9f2/080708&text=5" alt="Slide 5" />
</a>
</div>
<ul>
<li class="tkp-slide-btn tkp-slide-btn-prev">
❮
</li>
<li class="tkp-slide-btn tkp-slide-btn-next">
❯
</li>
</ul>
</div>
</section>