jQuery anonymous function - javascript

I have some code (below) which I wrote for a small piece of text to fade in out through a cycle of around 4 paragraphs. It works, but whenever I bring up the Web Inspector, it just tells me that it's an 'Anonymous function'. This is really annoying. Does anyone know how to fix it?
Btw, the bit that it hightlights as an anonymous function is:
slides[current].fadeOut("slow");
slides[target].fadeIn("slow");
The whole extract of code is here:
$(document).ready(function() {
var About = {
init: function() {
var slide_images = $('#widget p')
slides = new Array(),
delay = 5,
current = 0;
slide_images.each(function(index) {
current = index;
slides.push($(this));
});
var interval = setInterval(function() {
target = (current < (slides.length - 1)) ? current + 1 : 0;
slides[current].fadeOut("slow");
slides[target].fadeIn("slow");
current = target;
}, delay * 750);
}
}
About.init();
});
I made a jsfiddle here.

Because it is an anonymous function, as opposed to a named function.
One potential solution could be to roll the code into a named function and reference that function by named for the init option.

Related

User interaction conflict during SetTimeout in Javascript

I am working on a WordPress (Javascript) plugin that alters text fields based on user interaction with an HTML5 slider. One of its effects is to reveal a <span> string one character at a time using SetTimeout to create a delay (a few ms) so the effect is perceptible. I'm accomplishing this by getting the DOM element's contents and then rebuilding it one character at a time.
The problem is that since SetTimeout is aynsynchronous, the user can potentially move the slider faster than a single reveal loop can complete, resulting in half-empty DOM elements that never get corrected.
Is there a way to prevent this, or alternatively, a way to accomplish the task that avoids the conflict altogether? I have tried turning off the EventListener (for the HMTL5) at various points in the delay loop but cannot find a place that avoids the issue. The other possibility is to load all the <span> contents into arrays in order to retain intact copies of everything ... but something tells me there's a better way to do it that I don't know.
Here is example code. Initialize() is called when the HTML page involved loads.
function Initialize () {
document.getElementById(name).addEventListener('input', UpdateSlider);
}
function UpdateSlider()
{ if (
// conditions
)
{ var cols = document.getElementsByClassName(attr+i);
RevealTextLines (cols);
}
// 'delay' is a global variable to set the delay length
function RevealTextLines (cols)
{
[].forEach.call(cols, function(el) {
var snippet = el.innerHTML;
el.innerHTML = '';
el.style.display = 'inline';
(function addNextCharacter(h) {
el.innerHTML = snippet.substr(0,h);
h = h + numchars;
if (h <= snippet.length) {
setTimeout(function() {
addNextCharacter(h);
}, delay);
}
})(1);
});
}
The boolean flag suggested above does not work in this case, but it did inspire the following solution:
Provided the number of iterations are known in advance (which in this case they are), define a global counter variable outside the functions. Before the SetTimeout loop, set it to the number of iterations and decrease it by 1 every time through. Then have the calling function proceed only when the counter's value is zero.
var counter = 0;
function Initialize () {
document.getElementById(name).addEventListener('input', UpdateSlider);
}
function UpdateSlider()
{ if ( counter == 0)
{ var cols = document.getElementsByClassName(classname);
RevealTextLines (cols);
}
function RevealTextLines (cols)
{
[].forEach.call(cols, function(el) {
timer = el.length;
var snippet = el.innerHTML;
el.innerHTML = '';
el.style.display = 'inline';
(function addNextCharacter(h) {
el.innerHTML = snippet.substr(0,h);
h++;
if (h <= snippet.length) {
setTimeout(function() {
addNextCharacter(h);
timer--;
UpdateSlider();
}, delay);
}
})(1);
});
}
If anyone knows a more efficient solution, I would remain interested.

How can i make this slider to automatic slideshow

this is my javascript code only work on click event and i want to make this auto slideshow. please help me i have no knowledge how to do it..
var wflSliders = ({});
var wflSlider = new Class({
Implements:[Options,Events],
initialize:function(options){
this.setOptions(options);
if(this.options.ribbon_behavior == 'scroll'){
this.wrapper = $('rand_products_wfl_'+this.options.id);
if(this.wrapper){
this.ribbon = this.wrapper.getElement('.jspw_ribbon');
this.scroll_r = this.wrapper.getElement('.jspw_scroll');
this.lt = this.wrapper.getElement('.jspw_ribon_button_lt');
this.rb = this.wrapper.getElement('.jspw_ribon_button_rb');
this.blocks = this.wrapper.getElements('.jspw_prod');
var blockSize = this.blocks[0].getComputedSize();
var dim = (this.options.orientation == 'hor')?'x':'y';
if(this.options.effect_block == 'single'){
this.offset=(dim=='x')?blockSize.totalWidth:blockSize.totalHeight;
}
One way to approach is that you can use a built-in function called setInterval in Javascript and after wrapping your code in a function call it in the interval you desire to have your slideshow speed.
Like the following:
setInterval(function(){
slideShow(); // Every second the function is called
},1000);
Check the documentation here for more understanding: MDN Documentation for setInterval function
UPDATE: Givi just proved to me (in the comments of my answer) that my answer was not right. It has high risk that you use my suggested approach and better to use setTimeout recursively like this:
function slideShow() {
setTimeout(function() {
slideShow();
}, 1000);
}
you can us slide show plugin. Good luck

Autoscroll with setInterval/clearInterval

Im relatively new to JS coding, and can't get this little number to work. Can anyone tell me what I'm doing wrong?
My JavaScript is:
incrementScroll = function() {
window.scrollBy(0, 3) ;
}
startScrollLoop = function() {
scrollLoopId = setInterval( "incrementScroll", 5) ;
}
stopScrollLoop = function() {
clearInterval( scrollLoopId ) ;
}
And my HTML is:
<button onclick="startScrollLoop()">AUTO SCROLL</button>
<button onclick="stopScrollLoop ()">STOP SCROLL</button>
Again, many thanks for help. New to all of this and need to make a project work by morning.
Cheers.
The first argument to setInterval() should be a function reference, or non-ideally, a string to be eval()'d, which would be a complete function call with (). So remove the quotes:
// Pass the reference to incrementScroll,
// not a quoted string containing its name.
scrollLoopId = setInterval(incrementScroll, 5);
And to clear the scroll, you will need to define scrollLoopId at a higher scope with var.
// Define outside the function so it is available
// in scope of the stopScrollLoop() function when needed...
var scrollLoopId;
var startScrollLoop = function() {
scrollLoopId = setInterval( incrementScroll, 5) ;
}
Jsfiddle demo
(uses a slower scroll speed to give you a chance to click the stop button in the middle of the text)
Note that it is good practice to use the var keyword with each of these. even though they would end up at window scope anyway (assuming they're not being defined inside another function).
// Define with var
var incrementScroll = function() {
window.scrollBy(0, 3);
}

Animating a jquery set one object at a time

First, I'm relatively new to both js and jQuery, so I apologize in advance if this is a really stupid question. That said, here it is:
I'm trying to create a cannon-like animation for a background that does a slow 'sweep-like' transition from one image to another.
The biggest issue I've been running into is ensuring that;
a. The increment counter is progressed and;
b. Each 'slice' of the image completes its fadeOut before the next begins.
If there's an easy (or obvious) way of doing this, I'd love to hear it. I've been pulling my hair out for a while now trying to figure out why these (and other similar variations) aren't working.
HTML:
img class="bg" (10 instances of this)
(function () {
// --- Variation 1 ---
function effect() {
var i = 0,
var current = $(".bg_1:eq(" + i + ")"),
arrLength = $(".bg_1").length;
while (i < arrLength) {
current.fadeOut(1000, 0);
i++;
}
}
effect();
// --- Variation 2 ---
function effect() {
var i = 0,
var current = $(".bg_1:eq(" + i + ")"),
arrLength = $(".bg_1").length;
while (i < arrLength) {
current.fadeOut(1000, 0, function () {
i++;
});
}
}
effect();
})();
I think it may be a problem with the scope of the 'i' variable, or a conflict in jQuery at that depth of scope. Any possible solutions would be GREATLY appreciated!
Thanks.
Without seeing your html, it's a bit hard to answer, but here's a general way to animate multiple elements in sequence:
(function _loop(idx) {
var $elements = $('#wrapper .bg'), idx = idx % $elements.length;
$elements.eq(idx).fadeIn('slow').delay(2500).fadeOut('slow', function () {
_loop(idx + 1);
});
}(0));​
demo: http://jsfiddle.net/UU5AM/
Your var current will always be the same
try this:
function effect() {
var i = 0;
var arrLength = $(".bg_1").length;
while (i<arrLength) {
$(".bg_1:eq(" + i + ")").fadeOut(1000, 0);
i++;
}
}
effect();
Only now it will run as fast as the while loop goes. That means it will fade everything out almost immediately. You might want to run a setTimeout function for as long as the fadeOut goes:
var i = 0;
setTimeout(function(){
$(".bg_1:eq(" + i + ")").fadeOut(1000, 0);
i++;
}, 1000);
And ofcourse you will need to reset it when it reaches the end.
Edit:
Beat Richartz way, running the function again when the fadeOut is completed, is even better then the setTimeout.
You can use fadeOut's callback argument to provide it with a function which it will execute when the animation is completed. You can use this to raise the counter and (if necessary) animate the next element.
For example:
(function () {
function effect() {
var i = 0,
var current = $(".bg_1:eq(" + i + ")"),
arrLength = $(".bg_1").length;
var animateNext = function() {
current.fadeOut(1000, 0, function() {
i++;
if (i < arrLength) {
animateNext();
}
});
}
animateNext();
}
effect();
})();
As you can see, we've stored a reusable function in animateNext. We call it at the end of effect the first time to start the string of animation. After that, each next animation is started from the callback in fadeOut.
Your solutions are animating all the pictures at once. You have to install a recursive chain of events to do this:
// initial count value declared outside the function to not reinitialize
var count = 0;
function effect() {
// search the current image
var current = $(".bg_1:eq(" + count + ")");
// if there's an image, fade it out
if (current.length) {
current.fadeOut(1000, function() {
// increment the count;
count++;
// call the function recursively
effect();
});
}
}
// call the function
effect();
See it working with the JSFiddle here

scope collision while writing a jQuery plugin

I am trying to write a simple jQuery plugin just to see how its done. But i cant seem to run it twice simultaneously. Its basically a count down and all it does is get the text() value in a div and count it down until it reaches 1.
$('#box1').startCounter();
$('#box2').startCounter();
This call changes both this variables inside the function to point to #box2. Here is my jsfiddle
Its pretty confusing how this changes around in a jQuery plugin. thanks for any help :)
You defined $this in global scope, so when startCount is called on the second element, the value is overwritten. Use var to make it local:
var $this = this;
DEMO
Instead of invoking the function again the element, you could also do something like this:
$.fn.startCount = function(count, div) {
count = (count) ? count : parseInt($('span.no-display',this).text());
var $target = $('div.counter', this);
var run = function() {
if (count <= 1) {
this.fadeOut().mouseout();
}
else {
count--;
$target.text(count);
setTimeout(run, 1000);
}
};
run();
}
DEMO 2
And to make your plugin work in environments where $ does not refer to jQuery (jQuery.noConflict()), you should do:
(function($) {
$.fn.startCount = ...
}(jQuery));

Categories