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");
}
});
}
Related
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
I have a series of slide shows - a tad clunky, but they work.
var Slideshow = {
paginate: function () {
var slides = $('div.slide', '.allslideshow'),
total = slides.length;
$('.slideshow-nav-total').text(total);
slides.each(function (i) {
$(this).data('index', i + 1);
});
},
moveTo: function($a) {
var slide = $($a.attr('href'));
var wrapper = $('.slideshow-wrapper');
wrapper.animate({
left: -slide.position().left
}, 300, 'linear', function () {
$('.slideshow-nav-current').text(slide.data('index'));
$a.addClass('active').siblings('a').removeClass('active');
});
},
navigate: function () {
var self = this;
$('a', '.slideshow-nav').click(function (e) {
e.preventDefault();
if (self.interval) {
clearInterval(self.interval);
self.interval = false;
}
var $a = $(this);
var slide = $($a.attr('href'));
self.moveTo($a);
});
},
autoPlay: function() {
var $alist = $('a', '.slideshow-nav');
var i = 0;
var self = this;
this.interval = setInterval(function() {
var $a = $alist.eq(i++);
i %= $alist.length;
self.moveTo($a);
}, 1000);
},
init: function () {
this.paginate();
this.navigate();
$('.slideshow-nav-current').text(1);
this.autoPlay();
}
};
$(function () {
Slideshow.init();
});
});
The problem is.. The slideshows appear within jQuery show / hide content buttons on page. So, for instance if you click one content button, and then another content button; all the slideshows are still running in the background.
PROBLEM: I need to have the slideshow RESET each time a toggle button is clicked, so the user wont see the slide show start at slide 2 or 3 but must start at slide #1 every time!!
My toggle buttons / relevant click handler codes are below. Any suggestions to have slideshow restart from slide 1 every time content toggle buttons are selected?
$(document).ready(function() {
$("#star_btn1, #star_btn2, #star_btn3, #star_btn4, #star_btn5, #star_btn6, #star_btn7, #star_btn8, #star_btn9, #star_btn10,").each(function(c) {
$(this).delay(500 * c).fadeIn(600)
})
$(".w_stars").on("click mouseout mouseover", function(c) {
var l = $(this).attr("data-name");
$("#map").usmap("trigger", l, c.type, c)
})
reset:function(){
if (this.interval) {
clearInterval(this.interval);
this.interval = false;
}
this.moveTo($('.slideshow-nav').children().first());
var slides=$('.allthestates').children(':visible');
$(slides).find('.slideshow-nav a').first().addClass('active').siblings().removeClass('active');
},
init: function() {
this.paginate();
this.navigate();
$('.slideshow-nav-current').text(1);
this.autoPlay();
}
};
//(function($) {
//Slideshow.init();
//})(jQuery);
$('.w_stars').click(function(){
Slideshow.reset();
Slideshow.init();
})
I have an interactive illustration where you can hover over elements and then if you click on them you can see a popover and the clicked element gets black. It works quite good, but there is a problem with the click and hover code. If one clicks on the same element twice in a row and then on another element, the first element gets black. Try for yourself: http://labs.tageswoche.ch/grafik_osze
Here is the code:
var sourceSwap = function () {
var $this = $(this);
if (!$this.hasClass('active')) {
var newSource = $this.data('alt-src');
$this.data('alt-src', $this.attr('src'));
$this.attr('src', newSource);
}
};
var makeActive = function() {
var $this = $(this);
// bring the active back (if any) to the first state
if ($('img.active').length) {
var newSource = $('img.active').data('alt-src');
$('img.active').data('alt-src', $('img.active').attr('src'));
$('img.active').attr('src', newSource);
$('img.active').removeClass('active');
}
$this.toggleClass('active');
}
$(function() {
$('img[data-alt-src]')
.each(function() {
new Image().src = $(this).data('alt-src');
})
.hover(sourceSwap, sourceSwap);
$('img[data-alt-src]').on('click', makeActive);
});
To try for yourself: http://jsfiddle.net/8wtvvka5/
i tried this on fiddle:
function swap(e)
{
var src = e.attr('src');
var active = e.hasClass('active');
var dark = src.indexOf('_h.png', src.length - '_h.png'.length) !== -1;
e.attr('data-src-dark', dark);
if (active || e.attr('data-src-dark') == true) return;
e.attr('src', e.attr('data-alt-src'));
e.attr('data-alt-src', src);
return active;
}
var sourceSwap = function ()
{
if (!$(this).hasClass('active'))
{
swap($(this));
}
};
var makeActive = function()
{
var active = $(this).hasClass('active');
$('img.active').each(function()
{
$(this).removeClass('active'); swap($(this));
});
if (active) $(this).removeClass('active');
else $(this).addClass('active');
swap($(this));
}
$(function() {
$('img[data-alt-src]')
.each(function() {
new Image().src = $(this).data('alt-src');
})
.hover(sourceSwap, sourceSwap);
$('img[data-alt-src]').on('click', makeActive);
});
$('img.active') is a complete set of elements so you should use the 'each' function to handle them all
JUST COPY-AND-PASTE to fiddle to check it out yorself :)
I'm trying to run each animation function one after the other instead of all at once.
This is what I've got so far:
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(){
var widthpercent = $(this).attr("data-percent");
$(this).fadeIn();
$(this).animate({width:widthpercent},500);
});
});
I've tried using .delay() and setTimeout() in various combinations to no avail.
Could anyone point me in the right direction? Thank you!
It sounds to me like you're looking for animate's complete function. You can write a recursive function to keep calling the function in the complete function until all the items have been animated. To simplify: every time one element is animated, a callback is fired that animates the next element. That is the purpose of the complete parameter, so I'm certain that is what you're looking for.
Here's an example you can adapt to your specific needs.
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).animate({height: '30px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}
var current = 0;
animate($divs[current]);
Further, this same logic can be applied to your fadeIn. Just wrap fadeIn's callback around that logic, like this:
Live demo here (click).
var $divs = $('div');
function animate(element) {
$(element).fadeIn(function() { //now the animation is a callback to the fadeIn
$(element).animate({height: '70px'}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
});
}
var current = 0;
animate($divs[current]);
And here's your code: live demo here (click).
$(document).ready(function(){
var $divs = $('.bar');
function animate(element) {
$(element).fadeIn(function() { //you could unwrap this depending on what you're looking for
var widthpercent = $(element).attr("data-percent");
$(element).animate({
width:widthpercent,
duration: '500ms'
}, {
complete: function() {
if (current < $divs.length-1) {
++current;
animate($divs[current]);
}
}
});
}); //end fadeIn callback
}
var current = 0;
animate($divs[current]);
});
Try this:
var animate = function (el) {
return function () {
var widthpercent = el.data('percent');
el.fadeIn();
el.animate({
width: widthpercent
}, 500);
}
}
var bars = $('.bar');
bars.each(function (index) {
var $this = $(this);
setTimeout(animate($this), index * 500);
});
Fiddle
$(document).ready(function(){
var bars = $('.bar');
bars.each(function(i){
var widthpercent = $(this).attr("data-percent");
$(this).delay(i*800).animate({width:widthpercent,opacity:1,},500);
});
});
This will animate after delaying 800 * i milliseconds.
See this JSFiddle example.
I am having trouble working out how to create a simple pop-and-drop effect for a class of divs. Since the onmouseover events of each of the items in this class are currently calling the same function, rapidly mousing between divs leaves the previous div stuck halfway through (if you mouse on and off from the bottom of the div, you'll see the effect I'm trying to produce).
My current approach also calls for me to replicate quite a bit of code to call the function from each individual div's event handlers, so if there's a way to wrap those up into one function I'd really like to know how. I'm sure there's a simple and efficient way to do all this, just can't seem to work it out.
jsFiddle example: http://jsfiddle.net/DvXDb/
Here's my code (script at the bottom):
div.bouncer{
position:relative;
top:50px;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
var thisDiv; var nextDiv; var selDiv;
var containerDivList = document.getElementsByClassName("container");
var containerArray = Array.prototype.slice.call(containerDivList);
var container1 = containerArray[0];
var container2 = containerArray[1];
var container3 = containerArray[2];
var container4 = containerArray[3];
container1.onmouseover = function () {
callPop(this.getElementsByTagName('div')[0]);
}
container1.onmouseout = function () {
callDrop(this.getElementsByTagName('div')[0]);
}
container2.onmouseover = function () {
callPop(this.getElementsByTagName('div')[0]);
}
container2.onmouseout = function () {
callDrop(this.getElementsByTagName('div')[0]);
}
container3.onmouseover = function () {
callPop(this.getElementsByTagName('div')[0]);
}
container3.onmouseout = function () {
callDrop(this.getElementsByTagName('div')[0]);
}
var relativeHeights = ['0px', '5px', '10px', '15px', '20px', '25px', '30px', '35px', '40px', '45px', '50px'];
var index = 10;
var intervalHandle1;
function callPop(thisDiv) {
clearInterval(intervalHandle1);
selDiv = thisDiv;
intervalHandle1 = setInterval(popImage, 5);
}
function callDrop(thisDiv) {
clearInterval(intervalHandle1);
selDiv = thisDiv;
intervalHandle1 = setInterval(dropImage, 5);
}
function popImage() {
selDiv.style.top = relativeHeights[index];
index--;
if (selDiv.style.top === '0px') {
index = 0;
}
}
function dropImage() {
index++;
selDiv.style.top = relativeHeights[index];
if (selDiv.style.top === '50px') {
index = 10;
}
}
Here's an example using jQuery, you really should be using a Framework for things like this. They simplify everything.
http://jsfiddle.net/AEJY9/
$(function () {
$('.bouncer').hover(
function () {
$(this).stop().animate({
top: 10
}, 500);
},
function () {
$(this).stop().animate({
top: 50
}, 500);
}
);
});