I have an array with predefined lines:
var linesArr = ["asd", "dsa", "das"];
I have a div, which i created with JS and styled it with my CSS:
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
Right now i have that code that can animate the texts fadeIns and fadeOuts on click:
$(div).click(function(){
$(this).fadeOut(1000, function() {
$(this).text("Random text").fadeIn(2000);
});
});
But it is not a cycle that can iterate through my array items, it will be showing the predefined text all the time.
I tried to write a cycle that can work through that, but got lost:
$(div).click(function(){
for (var i = 1; i < linesArr.length; i++) {
$(div).fadeOut(1000, function() {
$(this).html(linesArr[i].fadeIn(2000));
});
};
});
That cycle is not working, i don't have any console errors, but the logic here is flawed. Can somebody help me?
Do you want like this
var linesArr = ["asd", "dsa", "das"];
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
document.body.appendChild(div);
$(div).click(function(){
//for (var i = 1; i < linesArr.length; i++) {
$(div).fadeOut(1000, function() {
index = linesArr.indexOf($(this).html()) + 1;
$(this).html(linesArr[index % linesArr.length]);
$("div").fadeIn(2000);
});
//};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can use a pointer (show in this case) to keep track of the current element being shown. Then on each click fade out the current and fade in the next.
I'm also using a module % to loop back to the first element when you reach the end.
var linesArr = ["asd", "dsa", "das"];
var show = 1;
var div = document.createElement("div");
div.className = "storyArea";
div.innerHTML = linesArr[0];
$(document.body).append(div);
$(div).click(function() {
$(div).fadeOut(1000, function() {
$(this).html(linesArr[show++ % linesArr.length]).fadeIn(2000);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If you need a cycle, you can use a loop in an IIFE:
$('div').click(function () {
(function loop(i) {
$('div').html(linesArr[i]).fadeOut(1000, function () {
$(this).html(linesArr[i]).fadeIn(2000);
i++;
if (i < linesArr.length) {
loop(i);
}
});
})(0);
});
var linesArr = ["asd", "dsa", "das"];
$('div').click(function () {
(function loop(i) {
$('div').html(linesArr[i]).fadeOut(1000, function () {
$(this).html(linesArr[i]).fadeIn(2000);
i++;
if (i < linesArr.length) {
loop(i);
}
});
})(0);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Click Me</div>
When the complete callback runs your i variable already reached the last value. In order to preserve the variable scope you can use IIFE
Related
Currently, this code is auto fade in and fade out div by selecting the div element the way they were arranged (consecutive order). What I want to do now is to make the selector in random, I want to fade in a random div and after fading it out it will pick another random div and infinite loop the process. Since I'm new in jQuery and so confused, I also want to know your opinion on how to put this such process on a If Else statement in the easiest way. Like for example, I will get the value of a number
int num = 1;
If(num == 1){
<!-- Do the process-->
}
Else {
<!-- Do another process by selecting from another set of divs-->
}
Here is the code:
jQuery.fn.nextOrFirst = function (selector) {
var next = this.next(selector);
return (next.length) ? next : this.prevAll(selector).last();
}
$(document).ready(function () {
$('div.mb').fadeOut(500);
var fadeInTime = 1000;
var intervaltime = 3000;
setTimeout(function () {
fadeMe($('div.mb').first());
}, intervaltime);
function fadeMe(div) {
div.fadeIn(fadeInTime, function () {
div.fadeOut(fadeInTime);
setTimeout(function () {
fadeMe(div.nextOrFirst());
}, intervaltime);
});
}
});
Divs:
<div class="boxes">
<div class="mb one">1-------------one</div>
<div class="mb two">2-------------two</div>
<div class="mb three">3-------------three</div>
</div>
Not sure if this is exactly what you want but can be modified:
var mb = $('.mb'),
mbl = mb.length;
mb.hide();
rand();
function rand(){
var r = getRand(0, mbl);
mb.eq(r).fadeIn('slow', function(){
$(this).fadeOut('slow', function(){
setTimeout(rand, 200);
});
});
}
function getRand(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
Try changing the nextOrFirst function to something like:
jQuery.fn.nextOrFirst = function (selector) {
var xCount = selector.size();
return Math.floor(Math.random() * xCount ) + 1;
}
Instead of getting the next of first div, this gets a count of all of the divs,
and pics a random number between 1 and X(the number of divs with your selector)
Try something like this,Hope it helps
var c=$(".boxes div");
setInterval(function(){
$.each(c,function(a,z){
$("div[class='"+(z.className)+"'").fadeIn();
});
var item = c[Math.floor(Math.random()*c.length)];
var u=item.className;
$("."+u).fadeOut();
$("div[class='"+u+"'").fadeOut(1000);
}, 3000);
EDIT:
var c=$(".boxes div");
setInterval(function(){
$.each(c,function(a,z){
$("div[class='"+(z.className)+"'").hide();
});
var item = c[Math.floor(Math.random()*c.length)];
var u=item.className;
$("."+u).fadeOut();
$("div[class='"+u+"'").show().fadeIn(1000);
}, 2000);
FIDDLE LINK: https://jsfiddle.net/bv0jj4wp/29/
I've got a problem with the last function. The goal is that when I click on the "suiv" div, the script start a loop with my div ".crea" that is out of the suiv div.
However, the loop this.div.find('.crea').each(function){} doesn't work.
$(document).ready(function(){
s = new slider(".galerie");
});
var slider = function (id) {
var self = this;
this.div = $(id);
this.nb = 0;
this.index = 0;
this.div.find(".crea").each(function () {
self.nb++;
//alert($(this).css("z-index"));
});
alert(this.nb);
this.index = 0;
this.suiv = this.div.find(".suiv");
this.prec = this.div.find(".prec");
this.suiv.click(function () {
this.div.find(".crea").each(function () {
//self.index=parseInt($(this).css("z-index"));
alert("wesh2");
}
});
}
Change find('crea') to parent('crea').children() and it will work.
find only goes downwards.
go up to the parent, then use children
this.suiv.click(function () {
this.div.parent.children(".crea").each(function () {
//self.index=parseInt($(this).css("z-index"));
alert("wesh2");
}
});
}
Im trying to implement this.value in a multiple elements add.EventListener context to activate the stuff to do on the element currently under the mouse:
var i = 0;
var max = 500; //ms DELAY MOUSE-IN
function time(){
i++;
if(i>max/10){
i=0;
ELEMENTS = document.getElementsByTagName('div');
for(i=0; i<ELEMENTS.length; i++) {
document.getElementsByTagName('div')[i].style.height = "100px";
}
clearInterval(interval1);
}
ELEMENTS = document.getElementsByTagName('div');
for(i=0; i<ELEMENTS.length; i++) {
document.getElementsByTagName('div')[i].innerHTML = i;
}
}
window.onload = function(e) {
ELEMENTS = document.getElementsByTagName('div');
for(i=0; i<ELEMENTS.length; i++) {
document.getElementsByTagName('div')[i].addEventListener('mouseover', function(){
interval1 = setInterval(time, 10); //ms intervalSpeed
}, false);
document.getElementsByTagName('div')[i].addEventListener('mouseout', function(){
clearInterval(interval1);
i = 0;
document.getElementsByTagName('div')[i].innerHTML = "0";
document.getElementsByTagName('div')[i].style.height = "80px";
}, false);
}
}
Actually in this code there are some repetition to improve, but what i want is to IMPLEMENT this.value to control the element currently under the mouse.
Here a DEMO: http://jsfiddle.net/voltk/uA5M2/
#YEM SALAT I'm sorry because I found a problem in your solution:
The timer of divs does not reset....
UPDATE: I found the problem: the function time() must be included into the window load, or the 'i' on mouseout is not defined.
Many thanks to YemSalat for his help.
You would need to bind the event listener callback to the current DOM element.
Otherwise, this will refer to the global scope (browser window)
From your example:
var _div = document.getElementsByTagName('div')[i];
_div.addEventListener('mouseout', (function(){
clearInterval(interval1);
i = 0;
this.innerHTML = "0";
this.style.height = "80px";
}).bind(_div), false);
}
}
Something like that.
EDIT: added a jsfiddle: http://jsfiddle.net/zAMK3/3/
I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});
Ok, so suppose. I have ten images in documents.images array. When I click on an image. How do I get an alert telling me what image I have clicked on.
EDIT
The reason that I want the index of the image I clicked on is because I am trying to bind it to an event and the previous way doesn't seem to work
document.images[i].addEventListener("click", function(){MakeMove(i)}, false);
This statement is in a for loop, and I intended it to bind to every image but that doesn't seem to be working.
Here is pure JavaScript way to do that:
window.onload = function() {
for (var i = 0; i < document.images.length; i++) {
var image = document.images[i];
image.setAttribute("index", i + "");
image.onclick = function() {
var index = this.getAttribute("index");
alert("This is image #" + index);
};
}
};
The trick is assigning custom attribute with the index, then read that attribute.
Live test case.
Put this at the bottom of the html file, just before the closing tag
<script type="text/javascript">
function listen(evnt, elem, func) {
if (elem.addEventListener) { // W3C DOM
elem.addEventListener(evnt,func,false);
} else if (elem.attachEvent) { // IE DOM
var r = elem.attachEvent("on"+evnt, func);
return r;
}
}
listen("click", document.getElementsByTagName("body")[0], function(event) {
var images = document.images,
clicked = event.target;
for(var i =0, il = images.length; i<il;i++) {
if(images[i] === clicked) {
return alert("You clicked on the " + (i + 1) + "th image");
}
}
});
</script>
window.onload = function() {
for (var i = 0; i < document.images.length; i++) {
var image = document.images[i];
image.onclick = function() {
var images = Array.prototype.slice.call(document.images);
alert(Array.indexOf(images,this));
}
};
};
JSFiddle: http://jsfiddle.net/kmendes/8LUzg/1/
If you want it to work on old browsers too add the function under Compatibility on https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf