I have three panels that have just text or text and images that I want to loop indefinitely, and be scalable from 1-1000 slides.
I have the following markup:
<div class="mb-panel-container cf">
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">
<h1>1.1</h1>
<p>slide 1.1</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>1.2</h1>
<p>slide 1.2</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>1.3</h1>
<p>slide 1.3</p>
<p class="datetime"></p>
</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">
<h1>2.1</h1>
<p>slide 2.1</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>2.2</h1>
<p>slide 2.2</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>2.3</h1>
<p>slide 2.3</p>
<p class="datetime"></p>
</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">
<h1>3.1</h1>
<p>slide 3.1</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>3.2</h1>
<p>slide 3.2</p>
<p class="datetime"></p>
</div>
<div class="mb-panel">
<h1>3.3</h1>
<p>slide 3.3</p>
<p class="datetime"></p>
</div>
</div>
</div>
And the following script:
<script>
$(document).ready(function() {
var items = $(".mb-panel"),
currentItem = items.filter(".active");
window.setInterval( function() {
var nextItem = currentItem.next();
currentItem.removeClass("active");
if( nextItem.length ) {
currentItem = nextItem.addClass("active");
} else {
currentItem = items.first().addClass("active");
}
}, 5000);
});
</script>
Unfortunately I am ending up with something like this:
Essentially, the first run of the panels work, but when it gets to the loops it stops for the other panels apart from column 1. I will be opening this up to allow the users to add as many notices per panel as they need, but require it to loop back to the beginning for each column once it reaches the last slide.
You have to pick the exact element with .eq(index) and change the index, depending - if it reached the max allowed length.
$('.mb-slider').each(function(){ // looping for each slider block
let panels = $(this).find('.mb-panel'); // collecting current slides
let len = panels.length;
let index = 0;
setTimeout(function loop(){
panels.eq(index).removeClass('active');
index = (index == len - 1) ? 0 : index + 1; // Google → Ternary operator
panels.eq(index).addClass('active');
setTimeout(loop, 1000);
}, 1000);
});
.mb-panel {
display: none;
border: 2px solid orange;
margin: 5px;
padding: 5px;
}
.mb-panel.active { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="mb-panel-container cf">
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">1-1</div>
<div class="mb-panel">1-2</div>
<div class="mb-panel">1-3</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">2-1</div>
<div class="mb-panel">2-2</div>
<div class="mb-panel">2-3</div>
<div class="mb-panel">2-4</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">3-1</div>
<div class="mb-panel">3-2</div>
<div class="mb-panel">3-3</div>
<div class="mb-panel">3-4</div>
<div class="mb-panel">3-5</div>
</div>
</div>
I've used self-calling setTimeout chain just because like that trick. Here you can use setInterval as well. But in some cases, it make sense - not to call function repetitively, while the previous step haven't completed yet.
Translated into native JS ( find 10 differences :D ):
let slider = document.querySelectorAll('.mb-slider');
for( let i = 0; i < slider.length; i++ ){
let panels = slider[i].querySelectorAll('.mb-panel');
let len = panels.length;
let index = 0;
setTimeout(function loop(){
panels[index].classList.remove('active');
index = (index == len - 1) ? 0 : index + 1;
panels[index].classList.add('active');
setTimeout(loop, 1000);
}, 1000);
}
.mb-panel {
display: none;
border: 2px solid orange;
margin: 5px;
padding: 5px;
}
.mb-panel.active { display: block; }
<div class="mb-panel-container cf">
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">1-1</div>
<div class="mb-panel">1-2</div>
<div class="mb-panel">1-3</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">2-1</div>
<div class="mb-panel">2-2</div>
<div class="mb-panel">2-3</div>
<div class="mb-panel">2-4</div>
</div>
<div class="mb-panel-section mb-slider">
<div class="mb-panel active">3-1</div>
<div class="mb-panel">3-2</div>
<div class="mb-panel">3-3</div>
<div class="mb-panel">3-4</div>
<div class="mb-panel">3-5</div>
</div>
</div>
Related
Here is my HTML with 3 questions and 3 answers:
<div class="faq-carousel">
<div class="all-questions question1">
<h4>Question 1</h4>
</div>
<div class="all-questions question2">
<h4>Question 2</h4>
</div>
<div class="all-questions question3">
<h4>Question 3</h4>
</div>
<div class=" all-answers answer1">
<p>Answer 1</p>
</div>
<div class=" all-answers answer2">
<p>Answer 2</p>
</div>
<div class=" all-answers answer3">
<p>Answer 3</p>
</div>
Here is my jQuery that shows/hides the 3 questions and answers:
jQuery(document).ready(function () {
"use strict";
jQuery(".all-answers").hide();
jQuery(".answer1").show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(".question1").addClass("highlighted");
var slideNumber = 1;
jQuery(".question1").click(function () {
jQuery(".all-answers").hide();
jQuery(".answer1").show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(".question1").addClass("highlighted");
slideNumber = 1;
});
jQuery(".question2").click(function () {
jQuery(".all-answers").hide();
jQuery(".answer2").show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(".question2").addClass("highlighted");
slideNumber = 2;
});
jQuery(".question3").click(function () {
jQuery(".all-answers").hide();
jQuery(".answer3").show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(".question3").addClass("highlighted");
slideNumber = 3;
}); });
How can I change the jQuery so that I can add more Q and A's to the HMTL without having to add more jQuery?
Many thanks!
The process you're trying to achieve here is to 'DRY' up your code, in other words, Don't Repeat Yourself.
To achieve what you need you can use common classes on the questions and answers, then relate the two together by their indexes, something like this:
"use strict";
jQuery(document).ready(function($) {
$('.question').click(function() {
$('.question').removeClass('highlighted');
var index = $(this).addClass('highlighted').index();
$('.answer').hide().eq(index).show();
});
});
.answer { display: block; }
.answer ~ .answer { display: none; }
.highlighted { background-color: #CC0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq-carousel">
<div class="question">
<h4>Question 1</h4>
</div>
<div class="question">
<h4>Question 2</h4>
</div>
<div class="question">
<h4>Question 3</h4>
</div>
<div class="answer">
<p>Answer 1</p>
</div>
<div class="answer">
<p>Answer 2</p>
</div>
<div class="answer">
<p>Answer 3</p>
</div>
</div>
Alternatively, if you want to explicitly link the elements together, due to HTML structure restrictions for example, then you can use data attributes to specify the relationships between elements:
"use strict";
jQuery(document).ready(function($) {
$('.question').click(function() {
$('.question').removeClass('highlighted');
var target = $(this).addClass('highlighted').data('target');
$('.answer').hide().filter(target).show();
});
});
.answer { display: block; }
.answer ~ .answer { display: none; }
.highlighted { background-color: #CC0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq-carousel">
<div class="question" data-target="#answer-01">
<h4>Question 1</h4>
</div>
<div class="question" data-target="#answer-02">
<h4>Question 2</h4>
</div>
<div class="question" data-target="#answer-03">
<h4>Question 3</h4>
</div>
<div class="answer" id="answer-01">
<p>Answer 1</p>
</div>
<div class="answer" id="answer-02">
<p>Answer 2</p>
</div>
<div class="answer" id="answer-03">
<p>Answer 3</p>
</div>
</div>
Use a data attribute with the answer id.
Add the eventListener to all questions at once using jQuery(".all-questions").click
use jQuery('.answer'+jQuery(this).data('answer')).show(); to show current answer.
this will use current element.
use jQuery(this).addClass("highlighted"); to add the class to current element
To add the slide number, use slideNumber = jQuery(this).data('answer');
jQuery(document).ready(function() {
"use strict";
jQuery(".all-answers").hide();
jQuery(".answer1").show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(".question1").addClass("highlighted");
var slideNumber = 1;
jQuery(".all-questions").click(function() {
jQuery(".all-answers").hide();
jQuery('.answer'+jQuery(this).data('answer')).show();
jQuery(".all-questions").removeClass("highlighted");
jQuery(this).addClass("highlighted");
slideNumber = jQuery(this).data('answer');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="faq-carousel">
<div data-answer="1" class="all-questions question1">
<h4>Question 1</h4>
</div>
<div data-answer="2" class="all-questions question2">
<h4>Question 2</h4>
</div>
<div data-answer="3" class="all-questions question3">
<h4>Question 3</h4>
</div>
<div class=" all-answers answer1">
<p>Answer 1</p>
</div>
<div class=" all-answers answer2">
<p>Answer 2</p>
</div>
<div class=" all-answers answer3">
<p>Answer 3</p>
</div>
Give all questions and answer elements a data-number attribute with the correct number then use
$(".all-questions").click(function() {
$(".all-questions").hide();
var slideNumber = $(this).data("number");
$(".answer"+slideNumber).show();
$(".all-questions").removeClass("highlighted");
$(this).addClass("highlighted");
}
With no changes to the HTML, something like this should do it :
jQuery(function ($) {
"use strict";
$('.all-questions').on('click', function() {
$('.all-answers').hide().filter('.answer' + $(this).index()).show();
$('.all-questions').removeClass('highlighted').filter(this).addClass('highlighted');
});
$(".question1").trigger('click');
});
Try this one. Very simple. The trick I used is to associated every question class name with it's answers class name. For instance, if Question 1 class name is question1, its answer class name is question1_answer. After that let the magic happen (you can add your style however you want. Just copy/paste and run that code an see what it does.
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
function myFunction(classname){
var answerClassName = "." + classname + '_answer';
$(answerClassName).show();
//Hide all other answers
var otherAnswers = document.body.getElementsByTagName("div");
var l = otherAnswers.length;
for(i=0 ; i<l ;i++){
if(otherAnswers[i].className == classname){
//do nothing
}else{
var otherAnswersClassName = "." + otherAnswers[i].className + '_answer';
jQuery(otherAnswersClassName).hide();
}
}
}
</script>
</head>
<body>
<div class="question1" onclick="myFunction(this.className)">
<h4>Question 1</h4>
</div>
<div class="question1_answer">
<p>Answer 1</p>
</div>
<div class="question2" onclick="myFunction(this.className)">
<h4>Question 2</h4>
</div>
<div class="question2_answer">
<p>Answer 2</p>
</div>
</body>
</html>
I have a page with 'previous' and 'next' buttons to traverse an array of divs.
Clicking next button will copy the next div indexed by the var 'click' into #place's innerHTML.
Clicking previous button will copy the previous div as you can imagine.
The problem is, when I click the button alternately(click previous and next and previous then next...), the div would remain as it is and will not change to the next or previous div, unless I click the same button twice.
A simple alert message would confirm the functions are executing when alternately clicked. What's going on? Thank you.
var clicks = 0;
var pageDivs = document.getElementsByClassName("plist");
var displayPanel = document.getElementById("place");
function g() {
if (clicks >= pageDivs.length) {
clicks = 0;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
clicks += 1;
}
function f() {
clicks -= 1;
if (clicks < 0) {
clicks = pageDivs.length - 1;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
.plist {
display: none;
}
#place {
background-color: lightskyblue;
min-height: 5%;
min-width: 10%;
}
<div id="place">
<p></p>
</div>
<div class="plist">
<p>Testing 1</p>
</div>
<div class="plist">
<p>Testing 2</p>
</div>
<div class="plist">
<p>Testing 3</p>
</div>
<div class="plist">
<p>Testing 4</p>
</div>
<div class="plist">
<p>Testing 5</p>
</div>
<button type="button" onclick="f()" style="width: 10%;">Previous</button>
<button type="button" onclick="g()" style="width: 10%;">Next</button>
You need to consistently add and subtract in the same place.
But no need for two functions
NOTE: for an additional improvement, just hide and show instead of inserting code into the DOM
var clicks = -1, // necessary for initial next clicking
pageDivs = document.getElementsByClassName("plist"),
displayPanel = document.getElementById("place"),
len = pageDivs.length;
function copyIt(direction) {
clicks += direction;
if (clicks >= len) clicks = 0;
else if (clicks < 0) clicks = len - 1;
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
.plist {
display: none;
}
#place {
background-color: lightskyblue;
min-height: 5%;
min-width: 10%;
}
<div id="place">
<p></p>
</div>
<div class="plist">
<p>Testing 1</p>
</div>
<div class="plist">
<p>Testing 2</p>
</div>
<div class="plist">
<p>Testing 3</p>
</div>
<div class="plist">
<p>Testing 4</p>
</div>
<div class="plist">
<p>Testing 5</p>
</div>
<button type="button" onclick="copyIt(-1)" style="width: 10%;">Previous</button>
<button type="button" onclick="copyIt(1)" style="width: 10%;">Next</button>
When you click Next, increment your counter first. You're doing it after, which is causing the issue.
Define your function f like this:
function g() {
clicks += 1; // increment at the start
...
}
var clicks = 0;
var pageDivs = document.getElementsByClassName("plist");
var displayPanel = document.getElementById("place");
function g() {
clicks += 1;
if (clicks >= pageDivs.length) {
clicks = 0;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
function f() {
clicks -= 1;
if (clicks < 0) {
clicks = pageDivs.length - 1;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
.plist {
display: none;
}
#place {
background-color: lightskyblue;
min-height: 5%;
min-width: 10%;
}
<div id="place">
<p></p>
</div>
<div class="plist">
<p>Testing 1</p>
</div>
<div class="plist">
<p>Testing 2</p>
</div>
<div class="plist">
<p>Testing 3</p>
</div>
<div class="plist">
<p>Testing 4</p>
</div>
<div class="plist">
<p>Testing 5</p>
</div>
<button type="button" onclick="f()" style="width: 10%;">Previous</button>
<button type="button" onclick="g()" style="width: 10%;">Next</button>
The problem was clicks counter was getting updated after updating the innerHTML.
Moving that to top fixed the issue.
$(document).ready(function() {
var clicks = -1;
var pageDivs = document.getElementsByClassName("plist");
var displayPanel = document.getElementById("place");
$("#prev").on("click", f);
$("#next").on("click", g);
function g() {
clicks += 1;
if (clicks >= pageDivs.length) {
clicks = 0;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
function f() {
clicks -= 1;
if (clicks < 0) {
clicks = pageDivs.length - 1;
}
displayPanel.innerHTML = pageDivs[clicks].innerHTML;
}
});
.plist {
display: none;
}
#place {
background-color: lightskyblue;
min-height: 5%;
min-width: 10%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="place">
<p></p>
</div>
<div class="plist">
<p>Testing 1</p>
</div>
<div class="plist">
<p>Testing 2</p>
</div>
<div class="plist">
<p>Testing 3</p>
</div>
<div class="plist">
<p>Testing 4</p>
</div>
<div class="plist">
<p>Testing 5</p>
</div>
<button id="prev" type="button" style="width: 10%;">Previous</button>
<button id="next" type="button" style="width: 10%;">Next</button>
I am trying to get a boolean that will let me know if a parent element has a child element. Some of the constraints are:
There can be x number of these "boxes"
Check and see for any of the boxes have a footer element
If the box does not have a footer element, add a class
<div class="data-trend">
<header></header>
<div class="main"></div>
<footer></footer>
</div>
<div class="data-trend">
<header></header>
<div class="main"></div>
<footer></footer>
</div>
<div class="data-trend">
<header></header>
<div class="main">
<span class="glyphicons"><span>
<!-- On the glyphicons I would add class if there is no footer -->
</div>
<!-- notice no footer -->
</div>
Moved the above comment into an actual answer:
var elems = document.querySelectorAll('.data-trend'),
len = elems.length,
i = -1
while(++i < len) {
if(!elems[i].querySelector('footer')) elems[i].classList.add('no-footer')
}
.no-footer { border: 3px solid blue; }
<div class="data-trend">
<header>Testing</header>
<div class="main"></div>
<footer>Footer</footer>
</div>
<div class="data-trend">
<header>Testing</header>
<div class="main"></div>
<footer>Footer</footer>
</div>
<div class="data-trend">
<header>Testing</header>
<div class="main">
<span class="glyphicons"><span>
</div>
</div>
If you're doing a lot of this in vanilla, it makes sense to define a forEach helper function for yourself
function forEach(elems, fn){
var len = elems.length,
i = -1
while(++i < len) {
fn(elems[i])
}
}
I'm using bootstrap carousel for the slider , on each slide there is some text over it.
I would like that text over the slides to aappear letter by letter.
I have almost solved it..
But there are 2 issues
On first slide the text doesn't come up at all
If the user goes to some other tab on the browser means if the current window is not in focus ,then everything gets messed up.
Here is my fiddle
HTML
<main>
<div class="container">
<div class="block-wrap">
<div id="js-carousel" class="carousel slide" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Chania">
<div class="caption">
<div class="mystring hide">companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Chania">
<div class="caption">
<div class="mystring hide">companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt "></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Flower">
<div class="caption">
<div class="mystring hide">2companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Flower">
<div class="caption">
<div class="mystring hide">3companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="overlay-effect"></div>
</div>
</div>
</div>
</div>
</main>
JS:
$(document).ready(function() {
$('#js-carousel').carousel({
interval: 5000
});
$('#js-carousel').on('slid.bs.carousel', function () {
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
var str = $(this).find(".active .mystring").html();
$('.active .demo-txt').html("");
showText(".active .demo-txt", str, 0, 100);
});
});
Instead of settimeout use setInterval function. Also use clearInterval to clear schedular when a new slide begin. (I think this is your second problem.)
Here is your target js file:
$(document).ready(function() {
$('#js-carousel').carousel({
interval: 5000
});
var handler;
var interval = 5000;
var index = 0;
function showText(target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index]);
}
}
function iteration() {
if(handler){
clearInterval(handler);
}
index = 0;
var str = $(this).find(".active .mystring").html();
$('.active .demo-txt').html("");
showText(".active .demo-txt", str, index++, 100);
handler = setInterval(function(){
showText(".active .demo-txt", str, index++, 100);
}, 100);
}
//on each carousel slide change:
$('#js-carousel').on('slid.bs.carousel', iteration);
//start immediately for your first problem:
iteration.bind($('#js-carousel'))();
});
It's because your function is inside the slide event. At starting, the carousel doesn't slide...
Fiddle: https://jsfiddle.net/Lbasa2jh/5/
JS:
$(document).ready(function() {
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
};
$('#js-carousel').carousel({
interval: 5000
});
var str0 = $(this).find(".active .mystring").html();
$('.active .demo-txt').html("");
showText(".active .demo-txt", str0, 0, 100);
$('#js-carousel').on('slid.bs.carousel', function () {
var str = $(this).find(".active .mystring").html();
$('.active .demo-txt').html("");
showText(".active .demo-txt", str, 0, 100);
});
});
The timer can be tricky when the tab goes inactive. I moved code around and cleared the timeout to make sure the timeout is clean when starting a new slide.
I noticed an issue (not always) when switching back from a different tab is that the carousel actually moves to next slide quicker than 5 second causing the text to be incomplete.
https://jsfiddle.net/vLwm58Ln/
$(document).ready(function() {
$('#js-carousel').carousel({
interval: 5000
});
var showText = function(target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
timer = setTimeout(function() {
showText(target, message, index, interval);
}, interval);
}
}, timer;
//First time, this triggers right away instead of waiting for the slide to move
showText(".active .demo-txt", $('#js-carousel').find(".active .mystring").html(), 0, 100);
$('#js-carousel').on('slid.bs.carousel', function() {
//clear any messed up timeout from prev slide
clearTimeout(timer);
//clear message that may be incomplete from the previous text animation
$('.prevActive').removeClass('prevActive').html('');
var str = $(this).find(".active .mystring").html();
$('.active .demo-txt').addClass('prevActive').html("");
showText(".active .demo-txt", str, 0, 100);
});
});
.carousel-inner {
position: relative;
}
.carousel-inner .overlay-effect {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
}
.carousel-inner .caption {
color: #ffffff;
font-weight: bold;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
height: 100px;
z-index: 9999;
left: 5%;
}
.carousel-inner .caption h1,
.carousel-inner .caption h2 {
font-weight: bold;
line-height: 1.6;
}
.carousel-inner .caption h1 {
font-size: 64px;
}
.carousel-inner .caption h2 {
font-size: 44px;
}
.carousel-inner .demo-txt {
border-bottom: 4px solid #ec8422;
padding-bottom: 5px;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<main>
<div class="container">
<div class="block-wrap">
<div id="js-carousel" class="carousel slide" data-ride="carousel">
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Chania">
<div class="caption">
<div class="mystring hide">companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Chania">
<div class="caption">
<div class="mystring hide">companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt "></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Flower">
<div class="caption">
<div class="mystring hide">2companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="item">
<img src="http://cdn.theatlantic.com/assets/media/img/photo/2015/11/images-from-the-2016-sony-world-pho/s01_130921474920553591/main_900.jpg?1448476701" alt="Flower">
<div class="caption">
<div class="mystring hide">3companies with Inbound Marketing</div>
<h4>We help <div class="demo-txt"></div> </h4>
</div>
</div>
<div class="overlay-effect"></div>
</div>
</div>
</div>
</div>
</main>
I have multiple div elements with same class dot under parent div like this
<div id="dots">
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
...
<div class="dot"> . </div>
</div>
How can I using JavaScript select all elements with class="dot" and on every 5 seconds apply certain class on random element.
randomElement.addClass('someClass');
What you need to do is basically first select all dots, then on each periodic activation run remove previously set class and set it again to random element with index within range from 0 to dots count - 1.
Here is an example.
var $dots = $('#dots .dot');
function activate() {
$dots.removeClass('active')
.eq([Math.floor(Math.random()*$dots.length)])
.addClass('active');
setTimeout(activate, 1000);
}
activate();
#dots .dot {
display: inline-block;
height: 50px;
width: 50px;
background: coral;
border-radius: 50%;
opacity: 0.2;
transition: opacity .3s ease;
}
#dots .dot.active {opacity: 1;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dots">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
How about this?
function addClassToRandomDotElement(){
var dotElements = document.getElementsByClassName('dot');
var totalDotElements = dotElements.length;
var randomNumber = Math.floor(Math.random() * totalDotElements ) + 1;
var randomDotElement = dotElements[randomNumber];
randomDotElement.addClass('someClass');
}
setInterval(function(){
addClassToRandomDotElement();
},5000);
Still one more different way, easy to understand.
DEMO
var noofdot = $(".dot").length;
setInterval(function () {
$(".dot").removeClass("someClass");
var x = Math.floor((Math.random() * noofdot) + 1);
$(".dot:nth-child(" + x + ")").addClass("someClass");
}, 5000);
.someClass
{
background:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="dots">
<div class="dot">.</div>
<div class="dot">.</div>
<div class="dot">.</div>...
<div class="dot">.</div>
</div>
Here is an iteration over all elements:
iteration over all elements
Add class to random elements
Remove that elements from the iteration list.
var elements = document.getElementsByClassName("dot");
setInterval(function() {
var random = Math.floor(Math.random() * elements.length);
elements[random].className += " extra";
delete elements[random];
}, 1000);
//change 1000 to 5000. This is the interval speed in milisec.
.extra {
font-size: 200%;
background-color: cornflowerblue;
width: 50px;
}
<div class="container">
<div class="dot">Test</div>
<div class="dot">Test</div>
<div class="dot">Test</div>
<div class="dot">Test</div>
</div>
I think the below should work for you.
window.radomNo = 0;
setInterval(function(){
if(radomNo) $(".dot:eq("+ radomNo +")").toggleClass("randomcss");
window.radomNo = Math.floor((Math.random() * $(".dot").length) + 1);
$(".dot:eq("+ radomNo +")").toggleClass("randomcss");
},1000);
.randomcss {
background : yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dots">
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
<div class="dot"> . </div>
</div>
http://jsfiddle.net/kishoresahas/7qgvru5p/
Here is another simple way:
function changeColor(){
var randInt = getRandomInt(0, $(".dot:not(.newStyle)").length -1);
$($(".dot:not(.newStyle)")[randInt]).addClass('newStyle');
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
setInterval(function(){
changeColor();
},3000);
.newStyle{background-color:green;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dot">testing</div>
<div class="dot">test</div>
<div class="dot">cool</div>
<div class="dot">more</div>
<div class="dot">cat</div>
<div class="dot">lol</div>
if you use jquery you can try the following:
randomElements = jQuery("div").get().sort(function(){
return Math.round(Math.random())-0.5
}).slice(0,5)