How to reuse a piece of Javascript multiple times in one page - javascript

I'm new to building websites and have a (probably quite basic) question about using a Javascript function that's been written for a slideshow. I have a one-page website which uses multiple slideshow units – made up of the slideshow div, holder and a counter (e.g. 1/4), all of which is controlled by the following js:
var currentSlide = 0
var totalSlides = $('.holder div').length
var nextSlide = function() {
console.log('nextSlide')
currentSlide = currentSlide + 1
if (currentSlide >= totalSlides) {
currentSlide = 0
}
var leftPosition = (-currentSlide * 100) + 'vw'
$('.holder').css('left', leftPosition)
var slideNumber = currentSlide + 1
$('.steps').text(slideNumber + '/' + totalSlides)
}
var prevSlide = function() {
currentSlide = currentSlide - 1
if (currentSlide < 0) {
currentSlide = totalSlides - 1
}
var leftPosition = (-currentSlide * 100) + 'vw'
$('.holder').css('left', leftPosition)
var slideNumber = currentSlide + 1
$('.steps').text(slideNumber + '/' + totalSlides)
}
var autoSlide = setInterval(function() {
nextSlide()
}, 100000000)
$('.next').on('click', function() {
clearInterval(autoSlide)
nextSlide()
})
$('.prev').on('click', function() {
clearInterval(autoSlide)
prevSlide()
})
var slideNumber = currentSlide + 1
$('.steps').text(slideNumber + '/' + totalSlides)
$('body').on('keydown', function(event) {
var keyCode = event.keyCode
if (keyCode == 37) {
clearInterval(autoSlide)
prevSlide()
}
if (keyCode == 39) {
clearInterval(autoSlide)
nextSlide()
}
})
My set up in HTML is this:
<main class="scroll-container">
<section id="project-1" class="toxic-yellow">
<div class="slideshow">
<div class="holder">
<div class="slide-1 image next"><img src="images/01.jpg"></div>
<div class="slide-2 image next">
<p class="project-text">
Project 1, 3D, 2020<br>
Insert the project text here insert the project text here insert the project text here insert the project text here insert the project text here
</p>
</div>
<div class="slide-3 image next"><img src="images/05.jpg"></div>
<div class="slide-4 image next"><img src="images/02.jpg"></div>
<div class="slide-5 image next"><img src="images/04.jpg"></div>
<div class="slide-6 image next"><img src="images/06.jpg"></div>
</div>
</div>
<p class="caption">Project 1</p>
<p class="steps"></p>
</section>
<section id="project-2" class="lilac">
<div class="slideshow">
<div class="holder">
<div class="slide-1 image next"><img src="images/05.jpg"></div>
<div class="slide-2 image next">
<p class="project-text">
Project 1, 3D, 2020<br>
Insert the project text here insert the project text here insert the project text here insert the project text here insert the project text here
</p>
</div>
<div class="slide-3 image next"><img src="images/05.jpg"></div>
<div class="slide-4 image next"><img src="images/02.jpg"></div>
<div class="slide-5 image next"><img src="images/04.jpg"></div>
<div class="slide-6 image next"><img src="images/06.jpg"></div>
</div>
</div>
<p class="caption">Project 2</p>
<p class="steps"></p>
</section>
And so on. I have 12 slideshows in total on the same page. The problem I'm encountering is that the script applies globally across the whole page but I'd like to control each slideshow independently of each other. Is there a way to reuse this script and apply it separately to each instance of the slideshow?
Thanks for your help!

You can use JavaScript Functions or Classes.
W3Schools Reference Functions
W3Schools Reference Classes

$('body').on('keydown', function(event)
With this you are applying change to all of the elements.
Judging by your code, you can trigger the event listener to change the slides only to the child elements of the parent element(section) which has id of "project-X". Have a look here

Related

Click a button that is visible in viewport

I have several buttons in div in an html page , I want to click the buy button which is visible in viewport , when I press the key B.
$(document).keydown(function(e) {
if (e.keyCode == 66) {
//click the visible buy button in viewport ,
$(".buy").click();
}
});
<section>
<div class="buy">BUY</div>
<div class="buy">SELL</div>
</section>
<section>
<div class="buy ">BUY</div>
<div class="buy ">SELL</div>
</section>
<section>
<div class="buy ">BUY</div>
<div class="buy ">SELL</div>
</section>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note : there are 100's of buy button , but only 1 buy button appears at a time in viewport
If other .buy buttons are invisible really, you can try this:
$(".buy:visible").click();
Else, get your visible section by this:
var myVisibleSection = document.elementFromPoint(x+10, y+10);
(The x and y are position of parent of your sections that is matches with visible section and you can get them by jquery (.offset()) or vanilla js. 10's are sum of border and padding of the parent.)
Now:
myVisibleSection.find(".buy").click();
You could try to use this convenient function which tells us if the button is visible in the viewport, which I found in this blog. Also please make the css class sell which is the same as buy and set it for the sell div's, since we need to distinguish between the two buttons!
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
$(document).keydown(function(e) {
if (e.keyCode == 66) {
//click the visible buy button in viewport ,
$(".buy").each(function( index ) {
if($(this).isInViewport()){
console.log($(this).html() + " - " + index);
$(this).click();
}
});
}
});
section {
height: 100vh;
width: 100%;
background-color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="buy">BUY</div>
<div class="sell">SELL</div>
</section>
<section>
<div class="buy">BUY</div>
<div class="sell">SELL</div>
</section>
<section>
<div class="buy">BUY</div>
<div class="sell">SELL</div>
</section>

Content slider with dynamic height

I'm using a slider from below website
http://callmenick.com/post/responsive-content-slider
This slider is responsive but i would like to know how to make the slider main div height auto adjust depending on the content.
This is the slider code
JS:
(function($) {
$.fn.cslide = function() {
this.each(function() {
var slidesContainerId = "#"+($(this).attr("id"));
var len = $(slidesContainerId+" .cslide-slide").size(); // get number of slides
var slidesContainerWidth = len*100+"%"; // get width of the slide container
var slideWidth = (100/len)+"%"; // get width of the slides
// set slide container width
$(slidesContainerId+" .cslide-slides-container").css({
width : slidesContainerWidth,
visibility : "visible"
});
// set slide width
$(".cslide-slide").css({
width : slideWidth
});
// add correct classes to first and last slide
$(slidesContainerId+" .cslide-slides-container .cslide-slide").last().addClass("cslide-last");
$(slidesContainerId+" .cslide-slides-container .cslide-slide").first().addClass("cslide-first cslide-active");
// initially disable the previous arrow cuz we start on the first slide
$(slidesContainerId+" .cslide-prev").addClass("cslide-disabled");
// if first slide is last slide, hide the prev-next navigation
if (!$(slidesContainerId+" .cslide-slide.cslide-active.cslide-first").hasClass("cslide-last")) {
$(slidesContainerId+" .cslide-prev-next").css({
display : "block"
});
}
// handle the next clicking functionality
$(slidesContainerId+" .cslide-next").click(function(){
var i = $(slidesContainerId+" .cslide-slide.cslide-active").index();
var n = i+1;
var slideLeft = "-"+n*100+"%";
if (!$(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-last")) {
$(slidesContainerId+" .cslide-slide.cslide-active").removeClass("cslide-active").next(".cslide-slide").addClass("cslide-active");
$(slidesContainerId+" .cslide-slides-container").animate({
marginLeft : slideLeft
},250);
if ($(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-last")) {
$(slidesContainerId+" .cslide-next").addClass("cslide-disabled");
}
}
if ((!$(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-first")) && $(".cslide-prev").hasClass("cslide-disabled")) {
$(slidesContainerId+" .cslide-prev").removeClass("cslide-disabled");
}
});
// handle the prev clicking functionality
$(slidesContainerId+" .cslide-prev").click(function(){
var i = $(slidesContainerId+" .cslide-slide.cslide-active").index();
var n = i-1;
var slideRight = "-"+n*100+"%";
if (!$(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-first")) {
$(slidesContainerId+" .cslide-slide.cslide-active").removeClass("cslide-active").prev(".cslide-slide").addClass("cslide-active");
$(slidesContainerId+" .cslide-slides-container").animate({
marginLeft : slideRight
},250);
if ($(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-first")) {
$(slidesContainerId+" .cslide-prev").addClass("cslide-disabled");
}
}
if ((!$(slidesContainerId+" .cslide-slide.cslide-active").hasClass("cslide-last")) && $(".cslide-next").hasClass("cslide-disabled")) {
$(slidesContainerId+" .cslide-next").removeClass("cslide-disabled");
}
});
});
// return this for chainability
return this;
}
}(jQuery));
HTML
<section id="cslide-slides" class="cslide-slides-master clearfix">
<div class="cslide-prev-next clearfix">
<span class="cslide-prev">prev slide</span>
<span class="cslide-next">next slide</span>
</div>
<div class="cslide-slides-container clearfix">
<div class="cslide-slide">
<h2>This is slide 1</h2>
<p>Slide 1 Content.</p>
</div>
<div class="cslide-slide">
<h2>This is slide 2</h2>
<p>Slide 2 Content.</p>
</div>
<div class="cslide-slide">
<h2>This is slide 3</h2>
<p>Slide 3 Content.</p>
</div>
<div class="cslide-slide">
<h2>This is slide 4</h2>
<p>Slide 4 Content.</p>
</div>
<div class="cslide-slide">
<h2>This is slide 5</h2>
<p>Slide 5 Content.</p>
</div>
</div>
</section><!-- /sliding content section -->
if the content is long in next or previous slides it will adjust fine. issue is cslide-slide parent div which is cslide-slides-master is not adjusting if the next slide content is shorter then the previous content.
I tried below code with no luck at all
$('.cslide-next').on('click', function(e){
e.preventDefault();
var parent = $('.cslide-slides-master'),
child = parent.children('.cslide-slide');
if (child.height() > parent.height()) {
parent.height(child.height());
}
});
Can anyone point me how to fix this issue?

HTML / JS horizontal scrolling DIV "list"

What I want to make is an horizontally scrolling DIV "list" just like pretty much every big web site in the internet(netflix for example).
I tried to make it using a main DIV which would be some kind of container, a 2nd div which holds all the content and is inside the first DIV and a lot of DIVs, one for each content module, that go inside the 2nd div.
the parts of the 2nd DIV that overflow the main one should hide, and the content could be shown by moving it(the 2nd DIV).
this is the best I could come up with, but it still doesn't work jsfiddle
This is my HTML
<button onmouseover="left=1" onmouseout="left=0">
<</button>
<div class="container">
<div id="filler" style="left:0px">
<div class="module" style="background:coral;">testing</div>
<div class="module" style="background:lightblue;">testing</div>
<div class="module" style="background:lightgreen;">testing</div>
<div class="module" style="background:salmon;">testing</div>
<div class="module" style="background:lightyellow;">testing</div>
</div>
</div>
<button onmouseover="right=1" onmouseout="right=0">></button>
CSS
.container {
height:50px;
width:200px;
overflow:hidden;
}
#filler {
height:50px;
width:250px;
position:relative;
border-radius:10px;
background:crimson;
}
.module {
width:50px;
height:50px;
border-radius:5px;
float:left;
line-height:50px;
text-align:center;
}
JavaScript:
var feft = 0
//feft stands for filler left
var right = 0
var left = 0
var loaded = 0
window.onload=function(){
loaded=1
}
function move() {
if(loaded == 1){
if (left == 1 && feft <= 250) {
//left == 1 && feft <= filler width
document.getElementById("filler").style.left = feft + 1
}
if (right == 1 && feft >= 0) {
//right == 1 && feft >= 0
document.getElementById("filler").style.left = feft - 1
} //these IFs tests if the filler should move
feft = document.getElementById("filler").style.left
//this sets the feft variable to what it needs to be for the next run of the function
}}
window.setInterval(move(), 100)
I have made a fiddle for you.
demo
HTML code
<button onmouseover="left=1" onClick="move(-1)"><</button>
<div class="container">
<div id="filler" style="left:0px">
<div class="module" style="background:coral;">testing</div>
<div class="module" style="background:lightblue;">testing</div>
<div class="module" style="background:lightgreen;">testing</div>
<div class="module" style="background:salmon;">testing</div>
<div class="module" style="background:lightyellow;">testing</div>
</div>
</div>
<button onmouseover="right=1" onClick="move(1)">></button>
JS Code
var position = 0;
var moduleCount = document.querySelector(".module").length;
window.move = function(number) {
if (number) {
position += number;
if (number == 0 || number > moduleCount) {
position = 0;
}
} else {
if (position <= 4) {
position++;
} else {
position = 0;
}
}
moduleOffset = document.querySelector(".module").offsetWidth;
filler = document.querySelector("#filler");
filler.style.left = -( position* moduleOffset) + "px";
}
setInterval(window.move, 3000);
What you want to do is called "Carousel". I suggest to use bootstrap for example and implement it then in your site.
http://getbootstrap.com/javascript/#carousel
Try adding overflow: scroll as a CSS property to your container div.

How do I stop clicking next too many times from breaking my image rotator?

Im new to jquery and have been trying to code a simple image rotator, it works well at the moment except for the fact that if you click the "next" of "prev" buttons too many times very quickly it will break the image rotator.
Here is the html:
<div id="viewport">
<div id="imageContainer">
<div class="image" style="background-color:red;">
<div class="title"><p>This is the title of the post</p></div>
</div>
<div class="image" style="background-color:green;">
<div class="title"><p>This is the title of the post</p></div>
</div>
<div class="image" style="background-color:yellow;">
<div class="title"><p>This is the title of the post</p></div>
</div>
<div class="image" style="background-color:brown;">
<div class="title"><p>This is the title of the post</p></div>
</div>
<div class="image" style="background-color:purple;">
<div class="title"><p>This is the title of the post</p></div>
</div>
</div>
</div>
<input type="button" name="prev" id="prev" value="prev" />
<input type="button" name="next" id="next" value="next" />
and jquery:
var ic = $('#imageContainer');
var numItems = $('.image').size();
var position = 0;
ic.css('left', '0px');
var inter;
var rotateTimeout;
function rotate(){
inter = setInterval(function(){
if (position == (numItems - 1)) {
console.log(position);
$('.image').first().insertAfter($('.image').last());
ic.css('left', '+=400px');
position--;
}
ic.animate({opacity: 0.2, left: "-=400px"}, 1500, function(){
ic.animate({opacity: 1.0}, 1000);
});
position += 1;
}, 6000);
}
rotate();
$('#prev').click(function () {
console.log(position);
if (position == 0) {
$('.image').last().insertBefore($('.image').first());
ic.css('left', '-=400px');
position++;
}
ic.animate({
left: "+=400px"
});
position -= 1;
clearInterval(inter);
clearTimeout(rotateTimeout);
rotateTimeout = setTimeout(rotate, 10000);
});
$('#next').click(function () {
if (position == (numItems - 1)) {
console.log(position);
$('.image').first().insertAfter($('.image').last());
ic.css('left', '-400px');
position--;
}
ic.animate({
left: "-=400px"
});
position += 1;
clearInterval(inter);
clearTimeout(rotateTimeout);
rotateTimeout = setTimeout(rotate, 10000);
});
Here is a demo of the rotator.
So how can I either stop the user from clicking the button too quickly, or perhaps only account for a click per two seconds to allow the rotator to do what it needs?
To limit function call frequency you can use some "Throttle" function. For example _.throttle from Underscore.js or any other implementation. It is not necessary to use whole library, only required function could be copied from there.
The event handler attachment will look like this:
$('#prev').click( _.throttle(function () { yours code... }, 2000) );

Image Slider Nav Links Jump to Anchor DIVs

I'm doing some work on a site I didn't build, and I'm running into an issue where the nav links for an image slider are making the browser jump to the DIV with that ID tag. It seems to be treating the nav links like anchor links to the DIVs, is there a way to keep the slider functionality, but disable the browser from jumping to those DIVs?
Here's the HTML:
<div class='slide-selectors'>
<div class="homepage-featured">Link 1</div>|
<div class="homepage-featured">Link 2</div>|
<div class="homepage-featured">Link 3</div>|
<div class="homepage-featured">Link 4</div>|
<div class="homepage-featured">Link 5</div>
</div>
<div id="homepage-slides">
<div id="image1" class="sliderContainer">
<img src="/img/img-01.jpg" width="1160" height="200"/>
</div>
<div id="image2" class="sliderContainer">
<img src="/img/img-02.jpg" width="1160" height="200"/>
</div>
<div id="image3" class="sliderContainer">
<img src="/img/img-03.jpg" width="1160" height="200"/>
</div>
<div id="image4" class="sliderContainer">
<img src="/img/img-04.jpg" width="1160" height="200"/>
</div>
<div id="image5" class="sliderContainer">
<img src="/img/img-05.jpg" width="1160" height="200"/>
</div>
</div>
And here's the JavaScript:
var $ = jQuery.noConflict();
var initialize;
function AnimateSlide(newSlide){
var clickedSlide = typeof newSlide !== 'undefined' ? newSlide : "auto";
// console.log("passed DOM id or auto ",clickedSlide);
var currentSlideId, currentSlideDOM, nextSlideId;
var nextSlideDOM = newSlide;
var slideCount = 0;
/* current slide check */
$('.slide-selectors').children('.homepage-featured').children('.tab').each(function(){
slideCount++;
if( $(this).hasClass('active') ) {
currentSlideDOM = $(this).attr('href');
$(this).removeClass('active');
currentSlideId = slideCount;
//console.log("active found: DOM", currentSlideDOM,"id", currentSlideId);
}
$(currentSlideDOM).hide();
});
/* end of current slide check */
// console.log("after loop: current active slide DOM",currentSlideDOM,"id", currentSlideId,"count", slideCount);
/* start of automation check */
if(clickedSlide != "auto" ) {
nextSlideDom = clickedSlide;
nextSlideId = parseInt(clickedSlide.replace("#image", ""));
// console.log('slide set to', nextSlideDOM, nextSlideId);
}
else {
if (currentSlideId == slideCount) {
nextSlideId = 1;
}
else {
nextSlideId = currentSlideId + 1;
}
$('#image' + currentSlideId).hide();
nextSlideDOM = "#image" + nextSlideId.toString();
// console.log("automated slide transition: new slide DOM", nextSlideDOM,"id", nextSlideId,"last slide id", currentSlideId);
}
/* end of automation check */
var nextSelectorId = "#slide-selector-" + (nextSlideId);
$(nextSlideDOM).show(); /* add active class to next slide */
$(nextSelectorId).addClass('active'); //.html(nextSelectorHTML);
};
function initializeSlides() {
var slideCount = 0;
$('.slide-selectors').children('.homepage-featured').children('.tab').each(function(){
slideCount++;
});
$('#homepage-slides').children('div').each(function() {
$(this).hide();
});
nextSlideId = Math.floor(Math.random()*(slideCount)) + 1;
nextSlideDOM = "#image" + nextSlideId.toString();
//console.log("random slide transition: new slide DOM", nextSlideDOM,"id", nextSlideId);
var nextSelectorId = "#slide-selector-" + (nextSlideId);
$(nextSlideDOM).show();
$(nextSelectorId).addClass('active');
//console.log("random slide transition: new slide DOM", nextSlideDOM,"id", nextSlideId, nextSelectorId);
initialize = false;
};
jQuery(document).ready(function($){
/******************** HOMEPAGE BANNER *************************
-show and hide the different featured items in the homepage banner section
-same function utilized for hiding and showing content in product tabs
*/
initialize = true;
initializeSlides();
setInterval(function() {
AnimateSlide();
},rSpeed);
$('.tab').click(function (e) {
var clickedSelector = $(this).attr('href');
AnimateSlide(clickedSelector);
});
});
You need to prevent the default action for the click event:
$('.tab').click(function (e) {
e.preventDefault();
var clickedSelector = $(this).attr('href');
AnimateSlide(clickedSelector);
});

Categories