Make Fullpage-Scroll-Script less static - javascript

Heyo,
I got a little Fullpage-Scroll-Script and I want to make it a bit less static. So instead of calling every single Div by a different Class (.one, .two, .tree...) I want to make the script work if all Divs have only one Class (.page). I tried it myself with the .each() function from jQuery ... but I couldn't get it to work.
Here is the current Script:
// Fullpage Scroll Script
function ScrollHandler(pageClass) {
var page = $('.' + pageClass);
var pageStart = page.offset().top;
var pageJump = false;
function scrollToPage() {
pageJump = true;
$('html, body').animate({
scrollTop: pageStart
}, {
duration: 1000,
easing:'swing',
complete: function() {
pageJump = false;
}
});
}
window.addEventListener('wheel', function(event) {
var viewStart = $(window).scrollTop();
if (!pageJump) {
var pageHeight = page.height();
var pageStopPortion = pageHeight / 2;
var viewHeight = $(window).height();
var viewEnd = viewStart + viewHeight;
var pageStartPart = viewEnd - pageStart;
var pageEndPart = (pageStart + pageHeight) - viewStart;
var canJumpDown = pageStartPart >= 0;
var stopJumpDown = pageStartPart > pageStopPortion;
var canJumpUp = pageEndPart >= 0;
var stopJumpUp = pageEndPart > pageStopPortion;
var scrollingForward = event.deltaY > 0;
if ( ( scrollingForward && canJumpDown && !stopJumpDown) || (!scrollingForward && canJumpUp && !stopJumpUp)) {
event.preventDefault();
scrollToPage();
}
} else {
event.preventDefault();
}
});
}
new ScrollHandler('one');
new ScrollHandler('two');
new ScrollHandler('three');
* {
margin:0;
padding:0;
}
.page {
height: 100vh;
}
.one { background-color: blue; }
.two { background-color: green; }
.three { background-color: orange; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page one"></div>
<div class="page two"></div>
<div class="page three"></div>
So instead of using:
new ScrollHandler('one');
new ScrollHandler('two');
new ScrollHandler('three');
I tried to use this:
$('.page').each(function() {
new ScrollHandler('page');
}
But it only worked for the first Div.

You need to pass $(this) in each loop and change the page variable to get directly the parameter :
// Fullpage Scroll Script
function ScrollHandler(pageClass) {
var page = pageClass;
var pageStart = page.offset().top;
var pageJump = false;
function scrollToPage() {
pageJump = true;
$('html, body').animate({
scrollTop: pageStart
}, {
duration: 1000,
easing: 'swing',
complete: function() {
pageJump = false;
}
});
}
window.addEventListener('wheel', function(event) {
var viewStart = $(window).scrollTop();
if (!pageJump) {
var pageHeight = page.height();
var pageStopPortion = pageHeight / 2;
var viewHeight = $(window).height();
var viewEnd = viewStart + viewHeight;
var pageStartPart = viewEnd - pageStart;
var pageEndPart = (pageStart + pageHeight) - viewStart;
var canJumpDown = pageStartPart >= 0;
var stopJumpDown = pageStartPart > pageStopPortion;
var canJumpUp = pageEndPart >= 0;
var stopJumpUp = pageEndPart > pageStopPortion;
var scrollingForward = event.deltaY > 0;
if ((scrollingForward && canJumpDown && !stopJumpDown) || (!scrollingForward && canJumpUp && !stopJumpUp)) {
event.preventDefault();
scrollToPage();
}
} else {
event.preventDefault();
}
});
}
$('.page').each(function() {
new ScrollHandler($(this));
})
* {
margin: 0;
padding: 0;
}
.page {
height: 100vh;
}
.one {
background-color: blue;
}
.two {
background-color: green;
}
.three {
background-color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="page one"></div>
<div class="page two"></div>
<div class="page three"></div>
JSfiddle: https://jsfiddle.net/fw8h7v4q/

Related

Slider Show does not works as ment to be- can't seem to find the problem

I want to create a slidershow made of some divs in a container. for some reason the slider messes everything up. Would appreciate any help with it.
$('[class^=show]').fadeOut(0)
var curClass = 3
var className = 'show-'
var fadeTime = 1000
var showTime = 3000
var cycleTime = (fadeTime * 2 + showTime) * (curClass + 1);
setInterval(function() {
for (var i = 0; i <= curClass; i++) {
cls = '.' + className + i;
// $(cls).fadeIn(fadeTime).delay(showTime).fadeOut(fadeTime);
$(cls).fadeIn(fadeTime, function() {
sleep(showTime);
$(cls).fadeOut(fadeTime);
});
}
}, cycleTime);
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
.container div {
height: 50px;
width: 50px;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='container'>
<div class="show-0">Hey 0</div>
<div class="show-1">Hey 1</div>
<div class="show-2">Hey 2</div>
<div class="show-3">Hey 3</div>
</div>
the slider should show each time one class of 'show-X' in order, fading in and out nicely.
Please see following:
$(document).ready(function () {
$('[class*=show-]').fadeOut(0);
var curClass = 3
var className = 'show-'
var fadeTime = 500
var showTime = 1000
var cycleTime = [(fadeTime * 2 + showTime) * (curClass + 1)] / 4;
var i = 0;
console.log(cycleTime);
setInterval(function () {
$('.' + className + i).fadeIn(fadeTime, function () {
//sleep(showTime);
try {
if (i == 0) { $('.' + className + curClass).fadeOut(fadeTime); } else { $('.' + className + (i-1)).fadeOut(fadeTime); }
} catch (e) { }
});
if (i == 3) { i = 0; } else { i++; }
}, showTime);
});
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
.container div {
height: 50px;
width: 50px;
background: red;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='container'>
<div class="show-0">Hey 0</div>
<div class="show-1">Hey 1</div>
<div class="show-2">Hey 2</div>
<div class="show-3">Hey 3</div>
</div>

Javascript prototype extend base-class unable to access base-class properties/methods from prototype class

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>
Problem 1: You are not returning anything from the prototype function. You have to return each public method as properties of the return Object.
return {
initSwiper : init,
method1 : method1,
method2 : method2,
};
Problem 2: You need to set variables inside the init function. Outside it this variable won't refer to TkpSlider.
// init();
function init() {
self=this;
var targetElements = document.getElementsByClassName(this.getItemClass());
addMultipleListeners(targetElements, 'mousedown touchstart', swipeStart);
addMultipleListeners(targetElements, 'mousemove touchmove', swipeMove);
addMultipleListeners(targetElements, 'mouseup touchend', swipeEnd);
return this;
}
Problem 3 You need to manually call the initSwiper() method to get your variables initialized when you create the TkpSlider Object.
var mainSwiper = new TkpSlider().initSwiper();
Then it will work as you need and you can call public methods if you need.
mainSwiper.method1();
mainSwiper.method2();
Working Snippet:
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;
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; //this.prototype.getItemClass()
;
// init();
function initSwiper() {
self = this;
var targetElements = document.getElementsByClassName(this.getItemClass());
addMultipleListeners(targetElements, 'mousedown touchstart', swipeStart);
addMultipleListeners(targetElements, 'mousemove touchmove', swipeMove);
addMultipleListeners(targetElements, 'mouseup touchend', swipeEnd);
return this;
}
function swipeStart(e) {
e.preventDefault();
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.preventDefault();
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);
}
}
}
return {
initSwiper: initSwiper
};
}();
var mainSwiper = new TkpSlider().initSwiper();
.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>
Prototype confusion: which this is this?
TkpSlider.prototype = function() {
console.log(this); /* this this is Child */
init();
function init() {
console.log(this); /* this this is Child, called from child context */
}
function initSwiper() {
console.log(this); /* this this is Parent, called from parent context */
}
function swipeStartEventHandler(event) {
console.log(this); /* this this is HTML element #customId*/
}
return {
initSwiper: initSwiper,
};
}();
new TkpSlider().initSwiper();

Make all div.obstacles have the same function

I am making a simple game that if the characters touch the "obstacle" which is another div the character that touches it will slow down while they are collided.
I already have a code for this, but it is only working for my .obstacle1 div even if I tried using jquery.each or I'm just missing something.
Here is the code which is working only for .obstacle1
HTML
<div class="field">
<div id="char1" class="characters character1">char1</div>
<div id="char2" class="characters character2">char2</div>
<div id="char3" class="characters character3">char3</div>
<div class="obstacles obstacle1">1</div>
<div class="obstacles obstacle2">2</div>
</div>
CSS
* {
padding: 0;
margin: 0;
}
.field-container {
overflow: scroll;
}
.field {
width: 1550px;
height: 700px;
border: 1px solid red;
position: relative;
}
.characters {
position: absolute;
width: 50px;
height: 50px;
transition: .1s ease-in-out;
}
.character1 {
background-color: blue;
top: 100px;
left: 0;
}
.character2 {
background-color: green;
top: 175px;
left: 0;
}
.character3 {
background-color: red;
top: 250px;
left: 0;
}
.obstacle1 {
height: 50px;
width: 50px;
background-color: lightblue;
position: absolute;
top: 200px;
left: 500px;
}
.obstacle2 {
height: 50px;
width: 50px;
background-color: lightblue;
position: absolute;
top: 120px;
left: 750px;
}
jQuery
$(document).ready(function(){
intervalCharacters = setInterval(function(){
moveChar();
},100);
function moveChar() {
$(".characters").each(function(){
move($(this));
});
}
/*--------------
OBSTACLES
---------------*/
var obstacle1 = $(".obstacles");
var obstacle1CurrentPosX = obstacle1.offset().left;
var obstacle1CurrentPosY = obstacle1.offset().top;
var obstacle1Height = obstacle1.outerHeight();
var obstacle1Width = obstacle1.outerWidth();
var totalY = obstacle1CurrentPosY + obstacle1Height;
var totalX = obstacle1CurrentPosX + obstacle1Width;
function checkIfCollidesChar(thisChar) {
var thisCharPosX = thisChar.offset().left;
var thisCharPosY = thisChar.offset().top;
var thisCharWidth = thisChar.outerWidth();
var thisCharHeight = thisChar.outerHeight();
var totalCharY = thisCharPosY + thisCharHeight;
var totalCharX = thisCharPosX + thisCharWidth;
if (totalY < thisCharPosY || obstacle1CurrentPosY > totalCharY || totalX < thisCharPosX || obstacle1CurrentPosX > totalCharX) {
return false;
console.log("FALSE");
} else {
return true
console.log("TRUE");
}
}
/* -----
move the characters
---- */
var moveFromLeft = 0;
var maxPosition = 1500;
function move(thisChar) {
var _this = thisChar;
var currentPosition = _this.offset().left;
var charSpeed = Math.floor(Math.random() * (10 - 0 + 1)) + 0;
if(checkIfCollidesChar(_this)) {
if(_this.offset().left > maxPosition) {
moveFromLeft = maxPosition;
}else{
moveFromLeft = currentPosition + (charSpeed*.25);
}
}else{
if(_this.offset().left > maxPosition) {
moveFromLeft = maxPosition;
}else{
moveFromLeft = currentPosition + charSpeed;
}
}
_this.css({
"left" : moveFromLeft,
});
if(moveFromLeft > maxPosition) {
checkIfFinish(_this);
_this.css({
"left" : maxPosition+"px",
});
}
_this.html(moveFromLeft);
}
});
Here is my fiddle.
Here's a fiddle with my suggested fix:
https://jsfiddle.net/40evn8pr/
The problem is that you're 'flattening' the obstacles jquery selection to a single value when you're directly asking for its offset/width/height. You should ask every element from the jquery selection what its offset is with an '$.each' loop to have every obstacle work.
$(document).ready(function(){
intervalCharacters = setInterval(function(){
moveChar();
},100);
function moveChar() {
$(".characters").each(function(){
move($(this));
});
}
var position = ["first","second","third"];
var counter = 0;
function checkIfFinish(thisChar) {
var position2 = position[counter];
counter++;
$(".result").append("<br>Position"+position2+ " counter" + counter + " : " + thisChar.attr("id"));
if(counter >= 3) {
clearInterval(interval);
}
}
/*--------------
OBSTACLES
---------------*/
var obstacle1 = $(".obstacles");
function checkIfCollidesChar(thisChar) {
var thisCharPosX = thisChar.offset().left;
var thisCharPosY = thisChar.offset().top;
var thisCharWidth = thisChar.outerWidth();
var thisCharHeight = thisChar.outerHeight();
var totalCharY = thisCharPosY + thisCharHeight;
var totalCharX = thisCharPosX + thisCharWidth;
var isCollision = false;
$.each(obstacle1, function(i, ob) {
var obstacle1CurrentPosX = $(ob).offset().left;
var obstacle1CurrentPosY = $(ob).offset().top;
var obstacle1Height = obstacle1.outerHeight();
var obstacle1Width = obstacle1.outerWidth();
var totalY = obstacle1CurrentPosY + obstacle1Height;
var totalX = obstacle1CurrentPosX + obstacle1Width;
if (!(totalY < thisCharPosY || obstacle1CurrentPosY > totalCharY || totalX < thisCharPosX || obstacle1CurrentPosX > totalCharX)) {
isCollision = true;
}
});
return isCollision;
}
/* -----
move the characters
---- */
var moveFromLeft = 0;
var maxPosition = 1500;
function move(thisChar) {
var _this = thisChar;
var currentPosition = _this.offset().left;
var charSpeed = Math.floor(Math.random() * (10 - 0 + 1)) + 0;
if(checkIfCollidesChar(_this)) {
if(_this.offset().left > maxPosition) {
moveFromLeft = maxPosition;
}else{
moveFromLeft = currentPosition + (charSpeed*.25);
}
}else{
if(_this.offset().left > maxPosition) {
moveFromLeft = maxPosition;
}else{
moveFromLeft = currentPosition + charSpeed;
}
}
_this.css({
"left" : moveFromLeft,
});
if(moveFromLeft > maxPosition) {
checkIfFinish(_this);
_this.css({
"left" : maxPosition+"px",
});
}
_this.html(moveFromLeft);
}
});
I think you are almost good. For your loop, you can use as model the
$(".characters").each(function(){
move($(this));
});
In your case, this would give :
$(".obstacles").each(function(){
var obstacle1 = $(this)
var obstacle1CurrentPosX = obstacle1.offset().left;
var obstacle1CurrentPosY = obstacle1.offset().top;
var obstacle1Height = obstacle1.outerHeight();
var obstacle1Width = obstacle1.outerWidth();
var totalY = obstacle1CurrentPosY + obstacle1Height;
var totalX = obstacle1CurrentPosX + obstacle1Width;
...
});

Why isn't it possible to change max-height with % in javascript?

I'm trying to build a responsive menu, with a hamburger icon. I want the menu list to slide in and out, no jquery - pure javascript only.
HTML :
<div id="animation">
</div>
<button id="toggle">Toggle</button>
CSS :
div {
width: 300px;
height: 300px;
background-color: blue;
}
Javascript :
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback){
var inter = -1, start = 100, end = 0;
if(type==true){
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function(){
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if(start == end){
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function(){
animate(hidden, function(){
hidden = (hidden == false) ? true : false;
});
}
div.style.maxHeight = "50%";
The problem is that proportional height in an element needs a fixed height on the parent, and you didn't provided any parent with a fixed height because for the maxHeight property too the % Defines the maximum height in % of the parent element.
You have to put your div in a parent container with a fixed height, this is your working code:
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback) {
var inter = -1,
start = 100,
end = 0;
if (type) {
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function() {
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function() {
animate(hidden, function() {
hidden = !hidden ;
});
}
div.style.maxHeight = "50%";
#animation {
width: 300px;
height: 300px;
background-color: blue;
}
#parent {
width: 500px;
height: 500px;
}
<div id="parent">
<div id="animation">
</div>
<button id="toggle">Toggle</button>
</div>
Note:
As stated in comments there are some statements in your JavaScript code that need to be adjusted:
if(type==true) can be written as if(type).
hidden = (hidden == false) ? true : false; can be shortened to hidden = !hidden
There seems to be a few errors with your code. I have fixed the js and added comments to what I have changed
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function (type, callback) {
var start = 100,
end = 0;
if (type) {
start = 0;
end = 100;
}
var si = setInterval(function () {
if (type) { // check whether to open or close animation
start++;
} else {
start--
}
div.style.maxHeight = start + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
callback.call(this); // do the callback function
}
var hidden = false;
but.onclick = function () {
animate(hidden, function () {
hidden = !hidden; // set hidden to opposite
});
}
/*make sure parent container has a height set or max height won't work*/
html, body {
height:100%;
margin:0;
padding:0;
}
div {
width: 300px;
height: 300px;
background-color: blue;
}
<div id="animation"></div>
<button id="toggle">Toggle</button>
Example Fiddle

How would I make these animations animate at different times?

I'm making a whack-a-mole game and this is what I have so far, I'm aware this is sloppy and probably isn't the easiest/smartest way to do this. What I need to know is how to get my animations to animate at separate times. This current code works to animate 9 different moles coming out of holes but I need them to animate at different times(so none of them will come up at the same time, or within a few milliseconds of eachother) My current code is
<html>
<body>
<style type="text/css">
body, a, a:hover {cursor: url(http://cur.cursors-4u.net/others/oth-5/oth438.cur),
progress;}
</style>
<body background = "http://i52.tinypic.com/34e9ekj.jpg">
<b><center><font size="5"><div id='counter'>0</div></font></center><b>
<b><center><i>Whack-A-Mole</i> - by Steven</center></b>
<div
style="
top: 37;
left: 350;
position: absolute;
z-index: 1;
visibility: show;">
<center><img id='animation0' src ='http://i51.tinypic.com/sxheeo.gif'/></center>
</div>
<div
style="
top: 37;
left: 33;
position: absolute;
z-index: 1;
visibility: show;">
<left><img id='animation1' src ='http://i51.tinypic.com/sxheeo.gif'/></left>
</div>
<div
style="
top: 37;
left: 700;
position: absolute;
z-index: 1;
visibility: show;">
<right><img id='animation2' src ='http://i51.tinypic.com/sxheeo.gif'/></right>
</div>
<div
style="
top: 200;
left: 352;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation3' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
<div
style="
top: 200;
left: 33;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation4' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
<div
style="
top: 200;
left: 700;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation5' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
<div
style="
top: 350;
left: 700;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation6' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
<div
style="
top: 350;
left: 33;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation7' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
<div
style="
top: 350;
left: 352;
position: absolute;
z-index: 1;
visibility: show;">
<img id='animation8' src ='http://i51.tinypic.com/sxheeo.gif'/>
</div>
</body>
<head>
<script type="text/javascript">
var urls;
function animate0(pos) {
pos %= urls.length;
var animation0 = document.getElementById('animation0');
var counter = document.getElementById('counter');
animation0.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation0.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation0.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate0(++pos);
}, (Math.random()*500) + 1000);
}
function animate1(pos) {
pos %= urls.length;
var animation1 = document.getElementById('animation1');
var counter = document.getElementById('counter');
animation1.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation1.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation1.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate1(++pos);
}, (Math.random()*500) + 1000);
}
function animate2(pos) {
pos %= urls.length;
var animation2 = document.getElementById('animation2');
var counter = document.getElementById('counter');
animation2.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation2.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation2.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate2(++pos);
}, (Math.random()*500) + 1000);
}
function animate3(pos) {
pos %= urls.length;
var animation3 = document.getElementById('animation3');
var counter = document.getElementById('counter');
animation3.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation3.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation3.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate3(++pos);
}, (Math.random()*500) + 1000);
}
function animate4(pos) {
pos %= urls.length;
var animation4 = document.getElementById('animation4');
var counter = document.getElementById('counter');
animation4.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation4.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation4.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate4(++pos);
}, (Math.random()*500) + 1000);
}
function animate5(pos) {
pos %= urls.length;
var animation5 = document.getElementById('animation5');
var counter = document.getElementById('counter');
animation5.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation5.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation5.onclick = function() {
//do nothing onclick
}
}
setTimeout(function() {
animate5(++pos);
}, (Math.random()*500) + 1000);
}
function animate6(pos) {
pos %= urls.length;
var animation6 = document.getElementById('animation6');
var counter = document.getElementById('counter');
animation6.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation6.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation6.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate6(++pos);
}, (Math.random()*500) + 1000);
}
function animate7(pos) {
pos %= urls.length;
var animation7 = document.getElementById('animation7');
var counter = document.getElementById('counter');
animation7.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation7.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation7.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate7(++pos);
}, (Math.random()*500) + 1000);
}
function animate8(pos) {
pos %= urls.length;
var animation8 = document.getElementById('animation8');
var counter = document.getElementById('counter');
animation8.src = urls[pos];
if (pos == 1) { // only make onclick when have a certain image
animation8.onclick = function() {
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}
}
else {
animation8.onclick = function() {
//do nothing
}
}
setTimeout(function() {
animate8(++pos);
}, (Math.random()*500) + 1000);
}
window.onload = function() { //Frames go below, seperated by commas format= , "URL");
urls = new Array("http://i51.tinypic.com/sxheeo.gif", "http://i56.tinypic.com/2i3tyw.gif");
animate0(0);
animate1(0);
animate2(0);
animate3(0);
animate4(0);
animate5(0);
animate6(0);
animate7(0);
animate8(0);
}
</script>
</head>
</html>
Generate 9 random numbers between 0 and your start time variation. Decide the max distance you want between the animations and scale the random numbers to that time frame. Then, set 9 timers to those times from now so each timer starts an animation.
If you wanted the animations to start over 500 milliseconds, you'd do something like this:
var randomTimes = [9];
for (var i = 0; i < 9; i++) {
randomTimes[i] = Math.floor(Math.random() * 501);
}
Now you have 9 random times spread out over 500 milliseconds and you can use those values with setTimeout to start each animation at a random time.
Copy/pasting a function this way is indeed sloppy!
You need to setup a flag:
var isMole = false;//at first there is no mole
if(!isMole){
//there is no mole, you can show one here
isMole = true;//there is a mole now!
}else{
//there is a mole, we wait.
}
Now set that flag to false when the mole times out or it struck by a hammer!

Categories