Removing self executing anonymous function - javascript

I am using an anonymous function and a Slider() function. I need all the same functionality in only one function. The anonymous function which I am using is should be removed. The below code should come into one function.
This is what I tried:
http://jsfiddle.net/QNZDX/5/
$(function() {
//FadeIn/FadeOut Image on Set Time Interval on Slide
timer=setInterval(Slider, mainInterval);
var div=$('<div id="paging_inner"></div>');
for(i=0;i<maximages;i++)
{
div.append($('<a id="page_'+(i+1)+'" data-index="'+(i+1)+'"><span></span></a>'));
}
$('#paging').append(div);
$('#paging a').on('click', function(e){
e.preventDefault();
clearInterval(timer);
prevIndex=$(this).attr('data-index')-1;
$('#paging div a span').stop(1,1);
Slider();
timer=setInterval(Slider, mainInterval);
});
});
function Slider() {
$('#imageSlide').fadeOut("slow", function() {
if (prevIndex >= maximages) prevIndex = 0;
$("#panel").fadeIn("slow").css('background', '#000');
var title = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("title").text();
$("#title").text(title).fadeIn("slow");
var imgurl = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("url").text();
$(this).attr('src', imgurl).fadeIn("slow");
var desc = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("desc").text();
$("#desc").text(desc).fadeIn("slow");
$('#paging a span')
.removeClass('active').css('display','block');
$('#paging a#page_'+(prevIndex+1)+' span')
.addClass('active')
.slideUp(mainInterval);
prevIndex++;
});
}
});

First of all,
It's more than an anonymous function - it's a self-calling anonymous
function
But in this case it is not necessary at all,
this will work same as previous
//FadeIn/FadeOut Image on Set Time Interval on Slide
timer = setInterval(Slider, mainInterval);
var div = $('<div id="paging_inner"></div>');
for (i = 0; i < maximages; i++) {
div.append($('<a id="page_' + (i + 1) + '" data-index="' + (i + 1) + '"><span></span></a>'));
}
$('#paging').append(div);
$('#paging a').on('click', function(e) {
e.preventDefault();
clearInterval(timer);
prevIndex = $(this).attr('data-index') - 1;
$('#paging div a span').stop(1, 1);
Slider();
timer = setInterval(Slider, mainInterval);
});
function Slider() {
$('#imageSlide').fadeOut("slow", function() {
if (prevIndex >= maximages) prevIndex = 0;
$("#panel").fadeIn("slow").css('background', '#000');
var title = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("title").text();
$("#title").text(title).fadeIn("slow");
var imgurl = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("url").text();
$(this).attr('src', imgurl).fadeIn("slow");
var desc = $xmldata.find("images").find("image:eq(" + prevIndex + ")").find("desc").text();
$("#desc").text(desc).fadeIn("slow");
$('#paging a span').removeClass('active').css('display', 'block');
$('#paging a#page_' + (prevIndex + 1) + ' span').addClass('active').slideUp(mainInterval);
prevIndex++;
});
}
Anything declared with "var" inside the function is private to that
function and cannot be accessed from outside it. That's actually the
main reason for using self-calling anonymous functions: to provide a
local scope where you can set up functions and variable without
cluttering the global namespace.
Look at the updated demo

Related

I'm not sure why my click event won't work

I'm trying to add a click event to .user that will change the background color of the entire page to green. I'm very new to jQuery, but the code looks right to me. When I click the .users button, nothing happens. Anyone have any ideas?
$(document).ready(function() {
var $body = $('body')
/*$body.html('');*/
// var currentView = "Twittler Feed"
var currentView = $('<p>Twittler Feed</p>');
var refreshTweet = function() {
var index = streams.home.length - 1;
var endInd = index - 10;
while (index >= endInd) {
var tweet = streams.home[index];
var $tweet = $('<div class="tweets"><p class="posted-by"><button class="user">#' +
tweet.user + '</button><p class="message">' + tweet.message +
'</p><p class="time">' + /*$.timeago(tweet.created_at)*/ tweet.created_at + '</p></div>');
currentView.appendTo('#sidebar')
$tweet.appendTo($body);
index -= 1;
}
}
refreshTweet();
$('.refresh').on('click', function() {
if (document.getElementsByClassName('tweets')) {
$('.tweets').remove();
}
var result = refreshTweet();
$body.prepend(result);
})
$('.user').on('click', 'button', function() {
currentView = this.user
$('body').css('background-color', 'green');
});
});

Same javascript twice cause the conflict on the slider

I'm trying to make an image slider and text slider on same page using same JavaScript. But some how it doesn't work properly as expected. I research some about this but only thing I found is to use no-conflict but it doesn't work either. When I exclude number-1 JavaScript code the number-2 slider works properly but when I include number 1 slider number 2 doesn't work properly. Is there a way I can avoid conflicting each other ? if so then how can I do this ? Here is my JavaScript code:
<script> //number-2
sliderInt = 1;
sliderNext = 2;
$(document).ready(function() {
$('#slider > img#1').fadeIn(150);
startSlider();
})
function startSlider() {
count = $('#slider > img').size();
loop = setInterval(function() {
if(sliderNext > count) {
sliderInt = 1;
sliderNext = 1;
}
$('#slider > img').fadeOut(150);
$('#slider > img#' + sliderNext).fadeIn(150);
sliderInt = sliderNext;
sliderNext = sliderNext + 1;
}, 3000);
}
function prev() {
newSlide = sliderInt - 1;
showSlide(newSlide);
}
function next() {
newSlide = sliderInt + 1;
showSlide(newSlide);
}
function stopLoop() {
window.clearInterval(loop);
}
function showSlide(id) {
stopLoop();
if(id > count) {
id = 1;
}else if(id < 1) {
id = count;
}
$('#slider > img').fadeOut(150);
$('#slider > img#' + id).fadeIn(150);
sliderInt = id;
sliderNext = id + 1;
startSlider();
}
$('#slider > img').hover(
function() {
stopLoop();
},
function() {
startSlider();
}
// In the End of the line don't put comma ','
);
</script>
<script> //number-1
textsliderInt = 1;
textsliderNext = 2;
$(document).ready(function() {
$('#slider_text > p#1').fadeIn(300)
textsliderStart();
})
function textsliderStart() {
count = $('#slider_text > p').size();
loop = setInterval(function() {
if(textsliderNext > count) {
textsliderInt = 1;
textsliderNext = 1;
}
$('#slider_text > p').fadeOut(300);
$('#slider_text > p#' + textsliderNext).fadeIn(300);
textsliderInt = textsliderNext;
textsliderNext = textsliderNext + 1;
}, 3000)
}
</script>
Put var in front of count = $('#slider_text > p').size(); and loop = setInterval(function() {
When you dont use var you declare count and loop at the global scope

Jquery Carousel - calculations if active slide is not one with specific ID then to slide to it.

The question isn't massively helpful I suppose so I'll try to be as clear as I can.
So I have a setup where my header has 4 anchor texts in them. The First part of the body has a custom jquery carousel in it.
What I'm trying to acheive is basically make it so that when any of the four anchor links in the header are clicked they scroll to a specific slide which I have given an ID. The issue I have of course is allowing for the carousel to have any slide active and having the anchor links calculate which slide is active and how much it needs to slide to get to the correct slide.
Here is the jquery for the carousel:
var carousel; // used as the object for the carousel
var carousels = []; // will hold any and all carousels on the page
var preventTimeouts = false;
var intervals = [];
$(document).ready(function () {
carousels.push(new carousel('slideshow_window', 'slidesHolder', '.slide', 920, 10000, 1000, true));
});
carousel = function CarouselSlider(windowName, slideCollectionWrapper,slideCollection, slideWidth, slideChangeInterval, slideChangeSpeed, requireNavButtons) {
// Variables
var slideWidth = slideWidth; // the width of each slide
var slides_array = $(slideCollection).toArray();
var numberOfSlides = slides_array.length;
var slideChangeInterval = slideChangeInterval; // how often the slides will automatically change
var slideChangeSpeed = slideChangeSpeed; // how fast the slides change
var slideIntervalId; // holds the interval event (the event for the next time that the slides should change)
var animating = false; // used to track whether an animation is underway
var currentPosition = 0; // used to highlight the centre image to begin with
var requireNavButtons = requireNavButtons;
var windowName = windowName;
var collectionWrapper = slideCollectionWrapper;
// Carousel
$('#' + windowName).append("<div id=\"" + collectionWrapper + "\"></div>"); // set up the collection wrapper
$('#' + collectionWrapper).css('width', slideWidth * numberOfSlides);
$('#' + collectionWrapper).css('position', "relative");
for (var i = 0; i < slides_array.length; i++) // add items from the collection to the wrapper
$('#' + collectionWrapper).append(slides_array[i]);
$('#' + collectionWrapper).css('left', 920 - slideWidth);
// for (i = 0; i < slides_array.length; i++) { // run one round of the carousel to ensure correct positioning
// currentposition++;
// moveslide(true, true); // set 'forced' to true to disable the animation
// }
function changePosition(forwards) {
forwards ? currentPosition++ : currentPosition--;
moveSlide(forwards, false);
}
function moveSlide(forwards, forced) {
var nextSlide;
animating = true;
if (forwards) {
nextSlide = currentPosition % numberOfSlides;
var t_dur = forced ? 0 : slideChangeSpeed;
$('#' + collectionWrapper).append(slides_array[nextSlide]);
$('#' + collectionWrapper).append(slides_array[nextSlide + 1 > numberOfSlides - 1 ? 0 : nextSlide + 1]); // load the next two slides
$('#' + collectionWrapper)
.animate({ left: "-=" + slideWidth, queue: false },
t_dur,
function () {
$('#' + collectionWrapper + ' ' + slideCollection + ':first').remove();
$('#' + collectionWrapper).css('left', 0);
animating = false;
});
}
else {
nextSlide = (currentPosition % numberOfSlides);
$('#' + collectionWrapper).prepend(slides_array[nextSlide - 1 < 0 ? numberOfSlides + nextSlide : nextSlide]);
$('#' + collectionWrapper).prepend(slides_array[nextSlide < 0 ? numberOfSlides + nextSlide : nextSlide]);
$('#' + collectionWrapper).css('left', 0 - slideWidth); // increase offset to account for prepended slides
$('#' + collectionWrapper)
.animate({ left: "+=" + slideWidth, queue: false },
slideChangeSpeed,
function () {
$('#' + collectionWrapper + ' ' + slideCollection + ':last').remove();
animating = false;
});
}
}
/*
Navigation buttons
*/
$("#next").click(function () {
if (!animating) { // only queue one click at a time
changePosition(true);
}
});
$("#prev").click(function () {
if (!animating) {
changePosition(false);
}
});
$("#prevSearch").click(function () {
if (!animating) {
changePosition(false);
}
});
$("#prevSearch2").click(function () {
$("#modalContainer").hide();
if (!animating) {
changePosition(false);
}
});
}

Animating an image carousel

I am using and have modified an image slider/carousel and need some guidance one two things. I need to enable it to auto scroll through the images firstly. and secondly I need to have three words underneath that act as controls too. So if I click on one it will take me to that image in the slider with some text underneath?
Example Fiddle
(function() {
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
carousel = $('.carousel');
carousel.prepend(last.clone()).append(first.clone());
carousel.width(itemWidth * $('.item').length);
carousel.css({left: -itemWidth});
$('.prev').on('click', function(e){
e.preventDefault();
carousel.animate({left: '+=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left) < 2) {
carousel.css({left: -itemWidth * (carousel.children().length - 2)});
}
});
return false;
});
$('.next').on('click', function(e){
e.preventDefault();
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
return false;
});
})();
so the image illustrates my aim.
Easiest way:
Create variable var autoplay=true;,
Wrap Your function binded to next button click in setInterval, so setInterval Function would be like this one:
setInterval(function(){
if(!autoplay)return;
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
})
},1000)
and then just add autoPlay toggle handler
$('.autoplayControl').on('click',function(){
autoplay=!autoplay;
})
FIDDLE: http://jsfiddle.net/UWbrQ/197/
Since I hadn't seen the button for autoplay I thought of automatic solution.
In This fiddle the Gallery moves with automatic movement(ten second for image) when the user clicks on pre next buttons auto move stops to restart after 10 seconds of inactivity
For me this is a more elegant solution
<script type="text/javascript">
$(document).ready(function(){
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
carousel = $('.carousel');
console.log(itemWidth)
carousel.prepend(last.clone()).append(first.clone());
carousel.width(itemWidth * $('.item').length);
carousel.css({left: -itemWidth});
//auto start
var giranews = setInterval(function(){move()},5000);
function move(){
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
};
function stopx(){
clearInterval(giranews);
};
function countdown(a) {
var count = a;
timerId = setInterval(function() {
count--;
console.log(count);
if(count == 0) {
clearInterval(timerId);
giranews = setInterval(function(){move()},5000);
};
}, 1000);
};
$('.prev').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
carousel.animate({left: '+=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left) < 2) {
carousel.css({left: -itemWidth * (carousel.children().length - 2)});
}
});
return false;
});
$('.next').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
return false;
});
})
</script>
The Easiest Way Demo Based On your Code with Just Addition of few Lines
Periodically Call the auto function
This function is basically the content inside your click for next slide
Wrap this inside the function and call it with your required interval
setInterval(Auto,5000);
function Auto(){
carousel.animate({left: '-=' + itemWidth}, 300, function(){
if(Math.abs(carousel.position().left + itemWidth * (carousel.children().length - 1)) < 2) {
carousel.css({left: -itemWidth});
}
});
}
Although the aim of this community is not provide complete script to other people, but provide solutions to specific problems, given my love for web galleries in this fiddle there is a gallery with caption below the image with buttons that move images
To accomplish this i had to change the script logic and code is increased slightly
If you like this solution don't forget to flag in green my answer ;) thanks
<script type="text/javascript">
$(document).ready(function(){
var first = $('.item').first(),
last = $('.item').last(),
itemWidth = first.width(),
countx=1,
carousel = $('.carousel');
console.log(carousel.position().left)
carousel.width(itemWidth * $('.item').length);
//auto start
var giranews = setInterval(function(){move()},5000);
function move(){
var left=carousel.position().left
if(left<(itemWidth*($('li.item').length-2)*-1)){carousel.animate({'left':'0px'},300)}else{ carousel.animate({left: '-=' + itemWidth}, 300);}
if(countx===4){countx=1}else{countx++}
showCaption(countx)
};
function stopx(){
clearInterval(giranews);
};
function countdown(a) {
var count = a;
timerId = setInterval(function() {
count--;
console.log(count);
if(count == 0) {
clearInterval(timerId);
giranews = setInterval(function(){move()},5000);
};
}, 1000);
};
//show captions in caption div
function showCaption(countx){
var caption=$('li:eq('+(countx-1)+')').attr('data-caption')
$('#caption').text(caption)
}
showCaption(countx)
$('.prev').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
if(countx===1){countx=4}else{countx--}
showCaption(countx)
var left=carousel.position().left
if(left===0){carousel.animate({'left':(itemWidth*($('li.item').length-1)*-1)+'px'},300)}else{carousel.animate({left: '+=' + itemWidth}, 300);}
});
$('.next').on('click', function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
if(countx===4){countx=1}else{countx++}
showCaption(countx)
var left=carousel.position().left
if(left<(itemWidth*($('li.item').length-2)*-1)){carousel.animate({'left':'0px'},300)}else{carousel.animate({left: '-=' + itemWidth}, 300);}
});
//insert buttons links to image
for(a=0;a<$('li.item').length;a++){
$('<a class="butt">'+(a+1)+'</a>').appendTo('div.buttons')
}
$('a.butt').click(function(e){
e.preventDefault();
stopx();
if(typeof timerId!=='undefined'){clearInterval(timerId);countdown(10)}else{countdown(10)}
var pos=carousel.position().left
carousel.animate({'left': (($(this).index()*itemWidth)*-1)+'px'})
showCaption($(this).index()+1)
countx=$(this).index()+1
})
})
</script>

jQuery / Javascript - loop

I want to make it so when I click somewhere in my website, the background changes. I have three backgrounds, and I want to make a loop of them.
$(document).ready(function() {
$('body').click((function(){
return function()
{
if (counter == null) {
var counter = 1;
}
if(counter == 3) {
$(this).css("background-image","url(3.jpg)");
$(this).css("background-position","10% 35%");
var counter = null;
}
if(counter == 2) {
$(this).css("background-image","url(2.jpg)");
$(this).css("background-position","10% 35%");
var counter = 3;
}
if(counter == 1) {
$(this).css("background-image","url(1.jpg)");
$(this).css("background-position","40% 35%");
var counter = 2;
}
}
})());
});
Why doesn't this work?
Your counter variable isn't scoped right, you need one counter variable. Overall though, why not let .toggle() manage this for you? Here's what it would look like:
$(function() {
$('body').toggle(function(){
$(this).css({"background-image":"url(1.jpg)", "background-position":"40% 35%"});
}, function() {
$(this).css({"background-image":"url(2.jpg)", "background-position":"10% 35%"});
}, function() {
$(this).css({"background-image":"url(3.jpg)", "background-position":"10% 35%"});
});
});
Although the name and common usages suggest that .toggle() only takes 2 functions, it actually takes 2 or more and will cycle through them.
this no longer refers to the body element, it refers to the anonymous function.
Does this code work?
var counter = 1;
$(document).ready(function() {
$('body').click(function() {
if (counter == null) {
counter = 1;
}
if (counter == 3) {
$(this).css("background-image", "url(3.jpg)");
$(this).css("background-position", "10% 35%");
counter = 1;
}
if (counter == 2) {
$(this).css("background-image", "url(2.jpg)");
$(this).css("background-position", "10% 35%");
counter = 3;
}
if (counter == 1) {
$(this).css("background-image", "url(1.jpg)");
$(this).css("background-position", "40% 35%");
counter = 2;
}
});
});
Your function uses this which is refering to itself, not the element. This would fix it:
$('body').click((function(){
var $this = $(this);
return ... {
$this // use $this instead of $(this)
Also, have a look on jQuery .toggle
Your counter declarations are strewn all over the place which makes it difficult to follow what's happening. Further, counter is declared local to the callback function, which means it loses its value every time the function executes.
Here's a simpler solution:
$(function() { // this is equivalent to $(document).ready(...)
var counter = 0;
var images = [
[ '1.jpg', '40% 35%' ],
[ '2.jpg', '10% 35%' ],
[ '3.jpg', '10% 35%' ]
];
$('body').click(function() {
$(this).css('background-image', 'url(' + images[counter][0] + ')');
$(this).css('background-position', images[counter][1]);
// increment counter, wrapping over to 0 when it reaches end of array
counter = (counter + 1) % images.length;
});
});
You can easily extend to this to any number of images by simply adding more entries to the images array.
$(document).ready(function () {
function changeBgImage() {
var imgs = [
["1.jpg", "10% 35%"],
["2.jpg", "10% 35%"],
["3.jpg", "40% 35%"]
];
var counter = 0;
return function() {
$(this).css({
"backgroundImage": "url(" + imgs[counter][0] + ")",
"backgroundPosition": imgs[counter][1]
});
counter += 1;
if (counter === imgs.length) { counter = 0; }
};
}
$('body').click(changeBgImage());
});
Update:
OK, so here we have another solution. It is basically Nick's answer but without redundancy.
$(function () {
var imgs = [["1.jpg", "10% 35%"], ["2.jpg", "10% 35%"], ["3.jpg", "40% 35%"]];
var i = 0;
$("body").click(function () {
$(this).css({"background-image": "url(" + imgs[i][0] + ")", "background-position": imgs[i][1]});
if (++i === imgs.length) { i = 0; }
});
});

Categories