swap images w/ jquery based on their existence on the server - javascript

I've been trying to figure out this semi-specific problem for the past couple days, and I could really use another pair of eyes on it.
My goal is to have an image on the page. It starts out as a static png, and when it's clicked, it swaps out with a .gif and plays an animation. When it's click on again, it swaps again and plays a second .gif animation. It does the same thing a third time. When the 3rd .gif is clicked on, it plays the 1st gif animation again, and the process starts all over again.
My issue is that multiple images are loaded on the page, and some have 3 total gif animations, some have 2, and some have one.
So what I'm trying to do is check if the .gifs exist before I load the next one.
Here's an excerpt with some of my notation...
$('#postContainer img').click(function () {
imgSrc = $(this).attr('src');
if(imgSrc.indexOf('_B.png') != -1){
imgSrcToUse = imgSrc.replace('_B.png', '_pt1.gif');
$(this).attr('src', imgSrcToUse);
return false;
}
That code above runs when the image is clicked. It finds the image src, and replace the static png with the first animated gif. all the images have an animated gif, so this isn't a problem.
if (imgSrc.indexOf('_pt1.gif') != -1) {
var POS2 = imgSrc.replace('_pt1.gif', '_pt2.gif');
$.ajax({
url: POS2,
type: 'HEAD',
error: function() {
alert('error');
imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt1.gif');
},
success: function() {
alert('success');
imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt2.gif');
}
});
$(this).attr('src', imgSrcToUse);
return false;
}
After _pt1 is loaded, then this function runs the next time you click. it is supposed to check if a _pt2 exists, and if it does, then swap out the pt1 with pt2. HOWEVER, it only seems to be working on the second click. if i click it once, it loads _pt1 again, and then the second time through it will load _pt2 properly. this is where my major problem lies...
i apologize if this is convoluted but i'm really stumped here. i'll try to do my best to clear things up if you guys are way too confused.

Here is your issue:
$.ajax({
url:POS2,
type:'HEAD',
error: function()
{
alert('error');
imgSrcToUse = imgSrc.replace('_pt1.gif','_pt1.gif');
},
success: function()
{
alert('success');
imgSrcToUse = imgSrc.replace('_pt1.gif','_pt2.gif');
}
});
$(this).attr('src',imgSrcToUse);
That last line of code is trying to use your variable imgSrcToUse, which doesn't contain the result of your AJAX query yet. AJAX is asynchronous, so your $.ajax call returns and moves onto the next line before the success (or error) callbacks are called. You can resolve this by moving the code using the data from the callbacks into the callbacks:
var $that = $(this);
$.ajax({
url: POS2,
type: 'HEAD',
error: function () {
alert('error');
var imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt1.gif');
$that.attr('src', imgSrcToUse);
},
success: function () {
alert('success');
var imgSrcToUse = imgSrc.replace('_pt1.gif', '_pt2.gif');
$that.attr('src', imgSrcToUse);
}
});
You were seeing sucess on the second call because you were assigning the next image name to a global variable. You should use var to avoid this.

Related

How to make setInterval run when browser tab is on focus?

I have created an Interval that runs on every 2 seconds, when the page loads. Now, when I move to other page, the interval is cleared (Please check the code). Now what I want is when I move to the same tab again, the interval should start again.
One thing I tried was that I wrote this whole code inside $(window).focus(//CODE) but the problem is that it doesn't run when the page is initially opened in any browser's tab.
How can solve this issue?
Here's my code:
var zzz= setInterval(anewFunc, 2000);
function anewFunc(){
$(document).ready(function(){
var chatattr=$(".chatwindow").css("visibility");
var chattitle=$("#hideid").text();
if(chatattr=="visible"){
$.ajax({
url: 'seen1.php',
type: 'post',
data: "ctitle="+chattitle,
success: function(result9){
},
error: function(){
}
});
}
$(window).blur(function(){
$.ajax({
url: 'session.php',
type: 'post',
success: function(result10){
// alert(result10);
},
error: function(){
}
});
clearInterval(zzz);
});
});
}
One thing I tried was that I wrote this whole code inside $(window).focus(//CODE) but the problem is that it doesn't run when the page is initially opened in any browser's tab.
Okay, the problem here is, the setInterval() doesn't execute at 0 seconds. It starts from 2 seconds only. So you need to make a small change:
Have the function separately.
Inside the ready event, start the timer, as well as run the function for the first time.
Remove the event handlers from the interval, or use just .one() to assign only once. You are repeatedly adding to the .blur() event of window.
Corrected Code:
function anewFunc() {
var chatattr = $(".chatwindow").css("visibility");
var chattitle = $("#hideid").text();
if (chatattr == "visible") {
$.ajax({
url: 'seen1.php',
type: 'post',
data: "ctitle=" + chattitle,
success: function(result9) {},
error: function() {}
});
}
$(window).one("blur", function() {
$.ajax({
url: 'session.php',
type: 'post',
success: function(result10) {
// alert(result10);
},
error: function() {}
});
clearInterval(zzz);
});
}
$(document).ready(function() {
var zzz = setInterval(anewFunc, 2000);
anewFunc();
});
Now what I want is when I move to the same tab again, the interval should start again.
You haven't started the setInterval() again.
$(document).ready(function () {
$(window).one("focus", function() {
var zzz = setInterval(anewFunc, 2000);
});
});

Error Loading AJAX on Document Ready Using JQuery

I'm trying to create a PHP page that periodically updates values of several elements on the page. I'm using a host that limits my hits per day, and each hit to any page they're hosting for me counts against my total. Therefore, I'm trying to use JQuery/AJAX to load all of the information that I need from other pages at one time.
I'm calling the following index.php. This method achieves the desired affect exactly the way I want it, but results in three hits (dating.php, dgperc.php, and pkperc.php) every two seconds:
var focused = true;
$(window).blur(function() {
focused = false;
});
$(window).focus(function() {
focused = true;
});
function loadData() {
if (focused) {
var php = ["dating", "dgperc", "pkperc"];
$.each(php, function(index, value) {
$('#'+this).load(this+'.php');
});
}
}
$(document).ready(function() {
loadData();
});
setInterval(function() {
loadData();
}, 2000);
I'm calling the following index1.php. This is where I'm at as far as a method that only results in one hit every two seconds. My workaround is that I have combined the three php pages that I was loading into one, dating1.php. I load this into a div element, #cache, all at once. This element is set to hidden using CSS, and then I just copy its inner HTML into the appropriate elements:
var focused = true;
$(window).blur(function() {
focused = false;
});
$(window).focus(function() {
focused = true;
});
function loadData() {
if (focused) {
var php = ["dating", "dgperc", "pkperc"];
$('#cache').load('dating1.php');
$.each(php, function(index, value) {
$('#'+this+'1').html($('#'+this).html());
});
}
}
$(document).ready(function() {
loadData();
});
setInterval(function() {
loadData();
}, 2000);
Dating1.php will produce different outputs every time it's run, but here is an example of the output:
<span id = "dating">4 years, 7 months, 3 weeks, 10 seconds ago.</span>
<span id = "dgperc">21.9229663059</span>
<span id = "pkperc">22.2121099923</span>
On document ready, index1.php does not function properly: the #cache element isn't filled at all, so the other elements don't get filled either. However, after two seconds, the loadData() function runs again, and then the #cache element is filled correctly, and so are the other elements. For some reason, this isn't a problem on my index.php page at all, and I'm not sure why there's a difference here.
How can I get #cache to load the first time so that the page loads correctly? Or is there a better way to do this?
Each AJAX call is basically a page visit in the background. Like telling your assistant three different times to get you one coffee. Or telling them one to get you three coffees.
If you don't want to combine your three PHP pages into one - thus keeping code separate and easier to maintain. Consider creating one "cache.php" script and inside it:
cache.php:
$outputData = array('dating' => false, 'dgperc' => false, 'pkperc' => false);
foreach($outputData as $file => &$data)
{
//buffer output
ob_start();
//run first script (be smart and file_exists() first)
include_once($file . '.php');
$data = ob_get_clean();
}
//output JSON-compliant for easy jQuery consumption
echo json_encode($outputData);
Then in your javascript:
function loadData() {
if (focused) {
//call ajax with json and fill your spans
$.ajax({
async: true,
cache: false,
dataType: 'json',
success: function(data, textStatus, jqxhr) {
$('#dating').html(data.dating);
$('#dgperc').html(data.dgperc);
$('#pkperc').html(data.dgperc);
// NOTE... do a console.dir(data) to get the correct notation for your returned data
},
url: 'cache.php'
});
}
You are calling cache.php once every two seconds, saving on the 3-hits of calling the php files individually. Using a middle-man file you keep your scripts separate for maintainability.

Jquery POST sending multiple variables

I've been trying to figure out this issue with my website for a while now--I have a bunch of "stars" a user can click on.
clicking on a star loads a file into a div with information regarding that star. It also loads a button for the players to click and "Take over" the planet. That all is working well and fine, however--I've recently discovered an issue that I'm not quite sure how to handle.
IF a player clicks on multiple stars before reloading the page for whatever reason--when the click to attack/whatever the star--it'll send multiple requests across the server. I at first thought this was something in my coding that was sending all information regarding all the stars, however I've come to realize that it's only the stars that the player has clicked on.
Now--Here is the code:
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
function loadStatus()
{
$.ajax(
{
url:'world1.php', error: function () { }, dataType:'json',
success: function(data)
{
denial = false;
$('#credits').html(data.credits);
$('#fuelleft').html(data.fuel);
$('#energyleft').html(data.energy);
}
});
}
function currentStarMapURL(URL)
{
$('#starmap').load(URL, {},
function()
{
$('#loader').hide();
fullStarInformation(URL);
starInformation();
setInterval(function() { $('.unknown').effect("highlight",{color:"#800000"}, 1500)});
return false;
}
);
}
/*
purhcase upgrades
*/
/*
Retriever Better Star Info
*/
function fullStarInformation()
{
$(".star").click(
function()
{
$('#planet-bar').empty();
val = this.id;
url = "planet.php?sid="+val;
$('#planet-bar').load(url, {'sid':val},
function()
{
colony(url);
}
);
}
);
}
function colony(url)
{
$('#planet-bar').on("click", "button",
function() {
event.preventDefault();
name = 0;
$(this).hide();
name = $(this).attr('sid');
$.post('purchase.php?mode=planet', {sid: name},
function ()
{
$('#planet-bar').load(url, {}, function () { currentStarMapURL(URL2); })
}
);
$(this).prop('disabled', true);
});
}
I figured at first that the issue was a caching issue, so I added the $.ajaxSetup to the first line, but that didn't seem to change anything.
Then I figured, maybe it's the way the code was being called--I originally had two seperate functions; one for attack, one for colonizing. both of which were being called in the fullStarInformation function, So I moved it all down to one function, i'm still getting the issue.
AFAIK, right now, i may have to rewrite this entire block of code so that the colony function and the starInformation function are separate and not acting upon one another. But I wanted to get a second, third maybe even fourth set of eyes on the code before I go about doing that.
If you are getting multiple ajax calls, chances are you are setting up multiple event handlers.
Just quickly glancing through the code, I would think you should change
function colony(url)
{
$('#planet-bar').on("click", "button", function() { ... } );
To
function colony(url)
{
$('#planet-bar').off("click", "button"); //unbind old event handlers
$('#planet-bar').on("click", "button", function() { ... } );

Loading Spinner Image too fast at start of Function

I have a function that displays contents of a posts when clicked on. I want the loading spinner to display and delay for few sections before the post content appears. The issue here is when I click on each post, the spinner appears for maybe 1ms and in some cases it disappears long before the content appears.
function showPost(id) {
setTimeout(function() {$('#loader').show();},1);
$('#pcontent').empty();
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
var $postcon = $('<div/>').append([$("<h3>", {html: data.post.title}),$("<p>", {html: data.post.content})]);
$postcon.appendTo('#pcontent');
});
}
Spinner HTML:
<div id='loader'><img src="css/images/loader.gif"/></div>
Try this:
function showPost(id) {
$('#loader').show();
$('#pcontent').empty();
$.ajax({
url: 'http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?',
dataType: 'json',
success: function (data) {
var $postcon = $('<div/>').append([$("<h3>", {
html: data.post.title
}), $("<p>", {
html: data.post.content
})]);
$postcon.appendTo('#pcontent');
$('#loader').hide();
}
});
}
gif image always behave differently on every device..basically it depends upon device's processing speed. so better option is to use image sprites and animate it with javascript..
In your case at page load there is nothing processing..but as page starts to load device's processor cant handle the load and as a result your gif image gets slower
It seems from your last commented line that you are using a timeout to hide the loader. Instead You should handle the hiding inside the callback function of your ajax request, so that loader hides after request is completed, not after a fixed amount of time:
function showPost(id) {
$('#loader').show();
$('#pcontent').empty();
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
$('#loader').hide();
var $postcon = $('<div/>').append([$("<h3>", {html: data.post.title}),$("<p>", {html: data.post.content})]);
$postcon.appendTo('#pcontent');
});
}

Jquery Random Slider doesn't show all images in json array

I'm writing my first jquery code and I've to write a random slider that will get images through a php function and will show them in a sequence with some decoration. Random thing is done in php. My jquery is as follows.
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(images) {
$.each(images, function (index, value) {
$('#banner').slideUp(500).delay(2000).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
});
}
});
}
I get images in images array and loop through it.
The problem I'm facing is that my this code only shows the last image in array. other images are not shown and it keeps sliding the last image of array.
But if I put an alert statement inside $.each function then image changes after I click on ok of alert box and it goes on.
Any help will be highly appreciated.
Please don't suggest to use some already built slider.
The each loop will run in microseconds and set the css value immediately on each pass with your code. Thus you only see the last image
Here's a solution using setTimeout and changing the css within the callback of the first animation so the css only gets changed at appropriate time. You may need to adjust the timeout interval index*3000
$.each(images, function(index, value) {
setTimeout(function() {
$('#banner').slideUp(500, function() {
/* use callback of animation to change element properties */
$(this).delay(2000).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
})
}, index * 3000);
});
DEMO using text change of element http://jsfiddle.net/RrPu6/
Following code is solution to the posted problem.
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(imgs) {
var cnt = imgs.length;
$(function() {
setInterval(Slider, 3000);
});
function Slider() {
$('#imageSlide').fadeOut("slow", function() {
$(this).attr('src', 'ItemPictures/'+imgs[(imgs.length++) % cnt]).fadeIn("slow");
});
}
}
});
}
where imageSlide is id of an img tag inside 'banner' 'div'
The problem is that you are iterating over the array of images, and for each one you're setting the background of the same DOM element... $('#banner'). This is going to happen so fast that you'll only see the last image, at the end of the iteration. This is also why you can see it changing if you alert() in between, because execution is paused during alert().
You'll have to figure out a way to delay the changing of the background. One thing you can try is adding an increasing delay() before your slideUp(). Something like:
function bannerSlide(){
$.ajax({
type: "GET",
url: "test.php",
dataType: 'json',
success: function(images) {
var duration = 2000;
var element = $('#banner');
$.each(images, function (index, value) {
element.delay(index * duration).slideUp(500).delay(duration).fadeIn(500).css('background', 'url(ItemPictures/'+value+')');
initialDelay += duration;
});
}
});
}
It's an ugly hack, but that's why those already built sliders exist :)

Categories

Resources