jQuery function attr() doesn't always update img src attribute - javascript

Context: On my product website I have a link for a Java webstart application (in several locations).
My goal: prevent users from double-clicking, i. e. only "fire" on first click, wait 3 secs before enabling the link again. On clicking, change the link image to something that signifies that the application is launching.
My solution works, except the image doesn't update reliably after clicking. The commented out debug output gives me the right content and the mouseover callbacks work correctly, too.
See it running here: http://www.auctober.de/beta/ (click the Button "jetzt starten").
BTW: if anybody has a better way of calling a function with a delay than that dummy-animate, let me know.
JavaScript:
<script type="text/javascript">
<!--
allowClick = true;
linkElements = "a[href='http://www.auctober.de/beta/?startjnlp=true&rand=1249026819']";
$(document).ready(function() {
$('#jnlpLink').mouseover(function() {
if ( allowClick ) {
setImage('images/jetzt_starten2.gif');
}
});
$('#jnlpLink').mouseout(function() {
if ( allowClick ) {
setImage('images/jetzt_starten.gif');
}
});
$(linkElements).click(function(evt) {
if ( ! allowClick ) {
evt.preventDefault();
}
else {
setAllowClick(false);
var altContent = $('#jnlpLink').attr('altContent');
var oldContent = $('#launchImg').attr('src');
setImage(altContent);
$(this).animate({opacity: 1.0}, 3000, "", function() {
setAllowClick(true);
setImage(oldContent);
});
}
});
});
function setAllowClick(flag) {
allowClick = flag;
}
function setImage(imgSrc) {
//$('#debug').html("img:"+imgSrc);
$('#launchImg').attr('src', imgSrc);
}
//-->
</script>

A delay can be achieved with the setTimeout function
setTimeout(function() { alert('something')}, 3000);//3 secs
And for your src problem, try:
$('#launchImg')[0].src = imgSrc;

Check out the BlockUI plug-in. Sounds like it could be what you're looking for.
You'll find a nice demo here.

...or just use:
$(this).animate({opacity: '1'}, 1000);
wherever you want in your code, where $(this) is something that is already at opacity=1...which means everything seemingly pauses for one second. I use this all the time.

Add this variable at the top of your script:
var timer;
Implement this function:
function setFlagAndImage(flag) {
setAllowClick(flag);
setImage();
}
And then replace the dummy animation with:
timer = window.setTimeout(function() { setFlagAndImage(true); }, 3000);
If something else then happens and you want to stop the timer, you can just call:
window.clearTimeout(timer);

Related

How to include mousewhell scroll and click event in the if statement?

How do I manage that if the user scrolls down the mouse wheel or clicks on $('#next') it will execute the function below?
var wd = event.originalEvent.wheelDelta;
if (wd < 0 || $("#next").click(function() {}) {
if (status == 1 && $('body').scrollTop() == $("#b1").offset().top) {
$('body').animate({
scrollTop: $("#b2").offset().top
}, 900);
prev.style.display = "block";
b1Slide_b('b1');
b1Slide('b2');
status = 2;
}
Include the code you want executed in a function, and then initiate both event to point to that function:
function stuffToDo(){
// the stuff you want to do here
}
$("#next").click(function() {
stuffToDo();
}
$("#next").scroll(function() {
stuffToDo();
}
This is not the cleanest way but it will allow you to give custom parameters to your function depending on the event, if you need.
Hope it helps
try something like this with your code.
made and example : jsfiddle
function myFunc() {
$(".content").css({"background":"red"})
};
$(window).scroll(function(){
if($(window).scrollTop()>0) {
myFunc();
};
});
$(".trigger").click(function(){
myFunc();
});
you need to do 2 separate functions in which you callback your function .
in myFunc() you insert everything you want to happen on scroll or on click
in this case changing the background color

Jquery Animations not waiting for callback

I have a Jquery animation that is running the code from its function before the animation is complete. the Page this code is being used at is no where near complete yet but if you want to take a look it's cottageboards.com/orderform
$('#snow').fadeIn(500, "linear", function () {
$('#largeImage').fadeOut(500, function () {
$('#largeImage').attr('src', selectedimg).load(function () {
$('#largeImage').fadeIn(1000, function () {
//Everything below here is running before the above image's fade in is complete
$('#snow').fadeOut(5000);
var selection = 'input[name="' + $(selectionage).data('type') + '_selection"]';
$($('#selected_thumb').val()).attr('src', $($('#selected_thumb').val()).data('regular'));
$(selectionage).attr('src', $(selectionage).data('selected'));
selectedid = '#' + $(selectionage).attr('id');
$('#selected_thumb').val(selectedid);
$('#selected_info').html($(selectionage).data('desc'));
$('#name').html($(selectionage).data('name'));
if ($(selectionage).data('val') === 99) {
$('#upload').show();
$('#displayinfo').hide();
} else {
$(selection).val($(selectionage).data('val'));
$('#upload').hide();
$('#displayinfo').show();
}
$('#next').prop('disabled', false);
});
});
});
});
When rewritten so the load function comes before the src change it works like a charm. Thanks for the help guys!
Working code:
$('#snow').fadeIn(500, "linear", function () {
$('#largeImage').fadeOut(500, function () {
$('#largeImage').unbind().load(function () {
$('#largeImage').fadeIn(1000, function () {
$('#snow').fadeOut(5000);
var selection = 'input[name="' + $(selectionage).data('type') + '_selection"]';
$($('#selected_thumb').val()).attr('src', $($('#selected_thumb').val()).data('regular'));
$(selectionage).attr('src', $(selectionage).data('selected'));
selectedid = '#' + $(selectionage).attr('id');
$('#selected_thumb').val(selectedid);
$('#selected_info').html($(selectionage).data('desc'));
$('#name').html($(selectionage).data('name'));
if ($(selectionage).data('val') === 99) {
$('#upload').show();
$('#displayinfo').hide();
} else {
$(selection).val($(selectionage).data('val'));
$('#upload').hide();
$('#displayinfo').show();
}
$('#next').prop('disabled', false);
});
}).attr('src', selectedimg);
});
});
You are binding the load function to largeimage every time you click. The first click the load function gets called once, the second time, it gets called twice. I suspect everything is getting messed up because you are firing multiple .fadeIns on the same object, and they are running in parallel.
Only call $('#largeImage').load(...) once, not on every click. Of course, you'll have to do something about your captured vars, but that's a different issue. Alternatively, call $('#largeImage').unbind().load(...)
If that's hard to follow, replace this line:
$('#largeImage').attr('src', selectedimg).load(function () {
with:
$('#largeImage').unbind().attr('src', selectedimg).load(function () {
I tested it by putting a break point after this line:
$('#thumbs').delegate('img','click', function() {
and calling $('#largeImage').unbind(); and everything seemed to work, so you can do it that way too.
see this fiddle for example how to use done : http://jsfiddle.net/gcnes8b2/1/
$('span').click(function() {
$('#1').fadeIn({
duration: 1000,
done:function(){
$('#2').fadeOut(1000);
// etc
}
});
});

How can I stop/pause a function from another function?

I have a simple jquery-ui slider which I am continuously automatically looping through values. I successfully have a button which starts the movement, but I forget how I can pause/stop the movement when another button is pressed? I know this is something really simple, but am having an absolute mind blank and google is not giving me what I want. (probably because i'm searching for the wrong wording). What can do I put in the pauseSlider function to ... pause the slider!
function scrollSlider() {
var slideValue;
slideValue = $("#slider").slider("value");
if (slideValue >= 0) {
if (slideValue == 2013) {
slideValue = -1;
}
$("#slider").slider("value", slideValue + 1);
console.log($("#slider").slider("value"));
setTimeout(scrollSlider, 1000);
}
}
$('#startSlider').click(function() {
scrollSlider();
});
$('#pauseSlider').click(function() {
//What do I put in here?
});
setTimeout returns a random number which you'll have to store in a variable and then use it to clear the setTimeout in $('#pauseSlider')'s click handler.
var id;
function scrollSlider() {
// (...) code
id = setTimeout(scrollSlider, 1000);
// (...) more code
}
$('#pauseSlider').click(function() {
clearTimeout(id);
});

Content slider like a slideshow

I have almost identical content slider like this one:
How could I make it rotate automatically? I have tried different ways but I cant make it work. I have tried putting a click on the link but it doesn't work:
i=1;
function autoplay(){
$('#navPoveznica'+i).click();
i++;
if(i>5){i=0};
setTimeout(autoplay, 2000);
}
And I called the function when DOM was .ready()
I'm really out of ideas, why doesn't this work? Can I select this way?
Should I use the class of the link and .each()?
It worked fine for me. Please check Demo.
Please paste your html,js fully so that we can have a check or set it up in jsfiddle.
What you can do is make an array of all the divs that needs to be slided like
//Define Variables
var divArray = [];
var delay: 6000;
var autoPlay: true;
var totalDivs: 5;
i = 1;
function createDivArray(){
$('#content_slider_container').find("div").each( function () {
divArray.push(this.attr('id'));
});
}
Then Write an AutoPlay Function Like this:
function autoPlay(divArray) {
ContentSlider = setInterval(function play(){
$(divArray).eq(i).slideLeft();
if (i >= totalDivs){
i = 0;
} else {
i++;
}
}
}, options.delay);
and Run the function like
autoPlay(divArray);

How to create a looped animation with JQuery

I have been sitting on this for a few hours and cannot figure this out. I am trying to create an slideshow (3 slides) that loops endlessly. Each slide is a li inside #slideshow. I have walked through this with a debugger and all variables get set correctly, but I don't understand why the animations dont actually happen. I have this which ends up displaying all images on the page:
$(document).ready(function() {
$slideshow = $('#slideshow');
$slideshowItems = $slideshow.find('li');
$slideshowItems.hide();
nextI = function(x) {
if ((x+1) < $slideshowItems.length) {
return x+1;
}
else {
return 0;
}
}
animation = function(i) {
$slideshowItems.eq(i).fadeIn(500).delay(1000).fadeOut(500, animation(nextI(i)));
}
animation(0);
If I do:
$slideshowItems.eq(0).fadeIn(500).delay(1000).fadeOut(500,
$slideshowItems.eq(1).fadeIn(500).delay(1000).fadeOut(500,
$slideshowItems.eq(2).fadeIn(500).delay(1000).fadeOut(500));
This works as expected, but it seems ugly and does not loop.
Any idea why I can't get this to work? I feel it is something with my expectations of how JQuery/ JS modifies the DOM or the sequence that the browser uses to execute animations. Thank you for the help!
var $slideshowItems = $('#slideshow').find('li'),
i = 0;
(function loop() {
$slideshowItems.eq( i ).fadeIn(500).delay(1000).fadeOut(500, loop);
i = ++i % $slideshowItems.length;
})();
JSFIDDLE DEMO
You should specify a callback method but your "animation(nextI(i))" returns nothing, so nothing remains to do after the fade out is complete.
Something like this I think will work:
var animation = function(i) {
$slideshowItems.eq(i).fadeIn(500).delay(1000).fadeOut(500, function (){
animation(nextI(i));
});
}
I would try setting that as a function and then using setInterval:
setInterval(function(){
$slideshowItems.eq(0).fadeIn(500).delay(1000).fadeOut(500, function() {
$slideshowItems.eq(1).fadeIn(500).delay(1000).fadeOut(500, function() {
$slideshowItems.eq(2).fadeIn(500).delay(1000).fadeOut(500);
});
});
}, 6000); // 6000 milliseconds before loops

Categories