Assistance with the creation of site offering lists based challenges - javascript

I want to develop a website that offers lists based challenges. The idea is based upon the website http://listchallenges.com where users can look at different types of lists and select the options that they have personally done (watched a movie, went to a place, etc.
Here is a part of my code :
function ($) {
$('#ig-thumbs').delegate('img','click', function()
{
if(record.indexOf($(this).parent().attr('id')) > -1 )
{
$(this).removeClass("counted");
if(a < 1)
{}
else
{
a=a-1;
document.getElementById("result").value=a;
record.pop($(this).parent().attr('id'),record);
}
}
else
{
record.push($(this).parent().attr('id') ) ;
$(this).addClass("counted")
a=a+1;
document.getElementById("text").value=a;
}
});
This code basically uses the variable a as the counter and displays its value in a text box called "result". "this" refers to a individual image that is being clicked which gets a class "counted" when it is clicked and the class is removed when it is clicked again. All of this is working fine but the problem arises in the dynamic updation of the variable a. Once a image is clicked the value of a increments by 1 but sometimes I have to click on the image twice to decrement the value.
For eg - If their are 8 items and I click on them once the value of a becomes 8 and gets displayed correctly. But when I click on all the images again the value does not become 0 but rather comes down to 1 or 2 and I have to click on the first or second image again to decrement the value to 0.
Can anybody help me in optimizing the code as I have tried many different things but I am unable to get it right.

<div id="result" >0</div>
<div id = "listImg">
<a class="cls" href="#"><img src="1.jpg"/></a>
<a class="cls" href="#"><img src="2.jpg"/></a>
<a class="cls" href="#"><img src="3.jpg"/></a>
<a class="cls" href="#"><img src="4.jpg"/></a>
</div>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(function() {
var count=0;
$('.cls').click(function() {
if($(this).attr("href")=="#"){
$("#result").html(++count);
$(this).attr("href","#ok");
}else{
$("#result").html(--count);
$(this).attr("href","#");
}
});
});
</script>
i hope this code help you :)

Related

Toggling images with javascript. My code works until I loop a php variable in the function. Can I do this?

I am trying to toggle between 2 button images for 2 elements. When I click 1 element I want to change the background image to make the button appear indented, but when I click the 2nd element I want the 1st to change back to how it originally was and change the 2nd element's image.
I found some JavaScript that almost did what I want, and I modified it to meet my needs and it worked perfectly in my test page, but when I put it into my actual site it behaves differently.
On my live page I have a database and I use PHP to loop 10 entries with these buttons.. When I click 1 element it changes as intended, but when I click the other element the first does not change back, and both elements are stuck on the 2nd image.
It seems like JavaScript doesn't like variables that are being looped with different values. I've messed around for hours trying to figure out the problem but I am at a loss. Here is the code in question
<? $grabvalue = $row['id']; ?>
<script>
function toggleClass(el){
var kids = document.getElementById('buttons<?php echo $grabvalue; ?>').children;
kids[0].className = "button1";
kids[1].className = "button2";
if (el.className == "button1"){
el.className = "button1_down";
}
if (el.className == "button2"){
el.className = "button2_down";
}
}
</script>
<span class='buttons' id='buttons<?php echo $grabvalue; ?>'>
<a href='#' class='button1' onClick='toggleClass(this)' id='button1'></a>
<a href='#' class='button2' onClick='toggleClass(this)' id='button2'></a>
</span>
I'm sure there's problems in this code, but it works. The problem starts when I start to loop the php array $row. When I do, both buttons work, and change images when I click on them, but they get stuck on the button1_down and button2_down images. If I don't loop $row and let it be static with 1 value it works as intended for the entry with that value. What is the problem ? How do I accomplish this?

javascript advance number onclick or on reload

I display a random DIV every time my webpage is reloaded using a simple function. This produces too many repeats because I only have seven divs.
<script type="text/javascript">
randomNumber = Math.floor(Math.random()*7+1);
window.onload = function() {
if (randomNumber == 1) {
document.getElementById("n1").style.display = "inline";
}
if (randomNumber == 2) {
document.getElementById("n2").style.display = "inline";
}
...[ETC. through 7]
}
}
</script>
I would like to solve this by replacing the "random number" with a predictable "progressing number". Can I advance a variable with every reload or onclick and execute the function to display each DIV in sequence? 1,2,3... displaying all seven divs before repeating.
I worry I would need cookies to do this with each individual visitor. Because the traffic is very low (likely one visitor at a time), perhaps I could use code from a page counter to achieve this.
I searched for any examples of this in action but found none. I would be very appreciative of any and all suggestions. Thanks for your time.
First of all, the random number you are generating, generates 3 everytime so no wonder you are getting all the repeats of third div.. change your random number generation code with this one:
var randomNumber = Math.floor(Math.random() * (7)) + 1;
This will generate a random number between 1 and 7 randomly. Then to display that particular div, instead of so many if or switch statements, you can simply do it in one line considering your div ids are n1, n2, n3 and so on..
document.getElementById("n"+randomNumber).style.display = "inline";
Put these two lines inside window.onload function so everytime window loads, a new random number gets generated and that div gets displayed.
This will work perfectly for many visitors as each visitor will get it's unique random number and that particular div will be displayed. No need to go into cookies or stuff like that.
See the Working snippet below, everytime you run it, a random div will be displayed:
var randomNumber = Math.floor(Math.random() * (7)) + 1;
document.getElementById("n"+randomNumber).style.display = "inline";
<div id="n1" style="display:none">DIV1</div>
<div id="n2" style="display:none">DIV2</div>
<div id="n3" style="display:none">DIV3</div>
<div id="n4" style="display:none">DIV4</div>
<div id="n5" style="display:none">DIV5</div>
<div id="n6" style="display:none">DIV6</div>
<div id="n7" style="display:none">DIV7</div>
EDIT: After understanding your question better (hopefully) and doing some research, i came up with a solution where you can retain the value of current div between page reloads, make a new html file on your computer, copy paste the following code and keep refreshing the page to see each div being displayed incrementally..
<!DOCTYPE HMTL>
<html>
<body>
<div id="n1" style="display:none">DIV1</div>
<div id="n2" style="display:none">DIV2</div>
<div id="n3" style="display:none">DIV3</div>
<div id="n4" style="display:none">DIV4</div>
<div id="n5" style="display:none">DIV5</div>
<div id="n6" style="display:none">DIV6</div>
<div id="n7" style="display:none">DIV7</div>
<script>
window.onload = function(){
if(window.name === "" || parseInt(window.name, 10) === 8) //this condition will be true when the page loads for the first time or the div values (window.name) exceeds 7 (Number of divs)
window.name = 1;
document.getElementById("n"+window.name).style.display = "inline";
window.name = parseInt(window.name,10) + 1; //incrementing the div number..
}
</script>
</body>
</html>
NOTE: Although the question has an accepted answer, I thought this was a closer to the question solution, so I posted it after reading the lines in the OP Can I advance a variable with every reload or onclick and execute the function to display each DIV in sequence? 1,2,3... displaying all seven divs before repeating. which meant that the OP author did not want to show them randomly through the divs.
You could use localStorage to make this happen. This will rotate through the 7 divs sequentially and display one at each page load and it's going to be user specific. That means, every user is assured to see all the divs sequentially.
if (typeof(Storage) != 'undefined') { // Check if localStorage is available in the browser
prevDiv = localStorage.getItem("myShowDiv"); // Fetch the previous that was shown to this browser
if (!isNaN(prevDiv)) prevDiv = parseInt(prevDiv); // If not first time
else prevDiv = parseInt('0'); // If it's first time
nowDiv = prevDiv + 1; // This div will be shown
if (nowDiv > 7) nowDiv = 1; // When all divs have been shown start from 1
localStorage.setItem("myShowDiv",nowDiv); // Save this div id for next page load
document.getElementById("div"+nowDiv).style.display = "inline"; // Show the div
}
Here's a fiddle

Rotating through divs (hide/fade in) with jQuery

I'm currently in the process of creating a news carousel. On the left panel i have the three titles of each news item, to the right i have an image associated with that news item, and in the bottom right i have three "navigational blocks" for each item.
In my example, when you click a link on the left, it will display the associated content in the larger right hand panel. This also applies for the navigational blocks in the bottom right. If you click one of those, the associated item will be displayed in the larger panel.
The last thing i need to achieve is an auto rotation of these news items. On load, item one will be displayed with "link 1" highlighted, and "block one" of the navigational blocks highlighted. After say, 10 seconds, "link 2" will become highlighted with the "block 2" highlighted and the associated content in the middle being displayed. So on, so forth.
http://codepen.io/anon/pen/wDiGy - Here's a code pen version of it so far.
Code highlighted below:
<div id="title-container">
<ul>
<li>
Link 1
</li>
<li>
Link 2
</li>
<li>
Link 3
</li>
</ul>
</div>
<div id="image-container">
<div class="image1 image" itemID="1">1</div>
<div class="image2 image" itemID="2">2</div>
<div class="image3 image" itemID="3">3</div>
<div id="circular-nav">
<li></li>
<li></li>
<li></li>
</div>
jQuery for selecting each item
$('.image:first').show();
$('.title, .circle-title').click(function(){
$('.image').hide();
var itemID = $(this).attr('itemID');
$('.image[itemID="' + itemID + '"]').fadeIn('fast');
});
I will be changing the HTML to integrate into the CMS i'm using, but the class names won't be changing.
Any assistance would be greatly appreciated.
UPDATE: I've managed to get 99% of the way there by fiddling around with it. I now have one hurdle. I'm using .next() to reach each item. If there are three items and it reaches the end, how do you return to the beginning? (PEN Updated)
Use a setInterval to trigger the tile change/image change function for every 10 seconds.
setInterval(function(){
//Code for changing the tile/image
},10000); //Milliseconds
You can put your existing function in a variable and use it for click as well as for interval. Also, since you're passing some information with the click, you can store the ids in an array and increment/reset counter after all the images have been cycled through.
Update:
Working Fiddle!
http://jsfiddle.net/hc4py/ (with only links stylized, not bullets)
setInterval(function () {
var $cur = $('a.active');
var i = $cur.closest('li').index(); //parent 'li' of first active link
$('.image:visible').hide(); //hide visible image
$cur.removeClass('active');
//if active 'a's parent li is the last one
if ($cur.closest('li').is(':last-child')) {
$('.image').eq(0).fadeIn('fast'); //show first image
$cur.closest('ul').find('li:first-child').find('a.title').addClass('active');
}
else {
$('.image').eq(i + 1).fadeIn('fast');//show next image
$cur.closest('li').next().find('a.title').addClass("active");
}
}, 2000);
.title.active{color:red;}
I found a simple solution which just involved an if statement to check the length of the item. Once it ended, it was able to loop around correctly.
setInterval(function () {
if ($('.image:visible').next().length === 0) {
$('.image').hide();
$('.image:first').fadeIn();
} else {
$('.image:visible').hide().next().fadeIn('fast');
}
}, 2000); //Milliseconds

Continuously fade a list of thumbnails on top of each other w/ Jquery (only showing 4 at all times?)

I'm not exactly sure how to tackle this one. I've checked out the jQuery "Cycle" plugin, but haven't seen any exmaples of what I really need.
How would you achieve fading in a list of thumbnails from the HTML (maybe something like:
<ul id="container">
<li class="thumbnail"> <img src="1.jpg"/> </li>
<li class="thumbnail"> <img src="2.jpg"/> </li>
<li class="thumbnail"> <img src="3.jpg"/> </li>
<li class="thumbnail"> <img src="4.jpg"/> </li>
<li class="thumbnail"> <img src="5.jpg"/> </li>
...more
</ul>
I've created a sample .GIF to explain what i'm trying to do:
-There are a total of 4 boxes showing at all times
-Jquery will pull the next image on the list, and fade it into one of the 4 boxes (random box every time). (image will fade in over the last image in the box).
-This should only happen if there are more than 4 images inside the list. (stay static if we only have 4)
-Would like to have the ability to add more images via HTML, not inside the JS...
----UPDATE------
Kalle seems to have the correct solution, the only thing missing is the ability to control how many visible thumbnails you see at all times.
I worked 5 (+ 2, ver 1.1) hours on your question. The biggest problem was the switch between two elements. It turns out, that there isn't any "swapping" function.. So I made an alternative.. You cant make this fading transition any better, but it is fairly close your GIF. If you want just to swap them nice and dirty, without any fade.. then that's very easy to make.
Anyways, I composed into a plugin:
JoeShuffle v1.1
A simple jQuery plugin to shuffle list. Very easy to install and use. Works like any other jQuery plugin. Just add jQuery to your page, include the script with necessary css file. Then, call it to some list and voila! You can change the interval-speed like this: $('#JoeShuffle').JoeShuffle({intervalSpeed: 2000});
As of Ver 1.1 also randomizes the list on the first load and enables to have this script hooked to multiple lists. Also you can set the max. number of displayed elements:
$('#JoeShuffle').JoeShuffle({displayElements: 4});.
JoeShuffle v1.1 [ Download (33.54 KB) - View demo (jsfiddle) ]
JoeShuffle v1.0 [ Download (65.12 KB) - View demo (jsfiddle) ]
NOTES
I'm not sure how crossbrowser it is and also it is very dirty and raw plugin. Surely could use some optimization, however it does work.
My examples use colorful boxes, but it really doesn't matter if there are images or whatever in the li element.
Some features:
Remembers the last slot/position, where the swap was made, and wont use it again. Otherwise it will look kinda a weird
You can set your own custom interval-speed
Shuffles whatever you put between the list tags. However, you should keep all of them in one size
(v1.1) Randomizes all the elements in the ul list on the first load.
(v1.1) Allows you to set the max. number of elements displayed at once
(v1.1) Enables you to have this script hooked to multiple lists at once
Currently it works like this. Whatever you put inside the li elements, it will shuffle them. If you have 5 elements, then it will hide one. And then basically take the hidden element and swap it with some random element. However, I will revisit it in ~15 hours and add the option, that you can set how many are being displayed. So you can actually have 10 elements in the list, but you will only display 4 at the time, there for making the randomization more dynamic.
Rev 1 notes
Since you wanted to randomize them on the first load. Then I added the rand() plugin to this script. This way it makes the first hide() loop very neat and also works as randomizer on the full list..even thought it actually doesn't randomize the list separately..meaning its faster. As I mentioned in the comments inside the scrip, rand() plugin by Alexander Wallin, is a must have in your jQuery collection.
As you can see, you can hook it to multiple lists from now on. That and also adding more elements to the list came up a new problem. That the script was loading slow and all the elements would be shown for few ms, on the first load. I fixed the problem, by adding the scripts includes inside the <head> and not after the contents of the page. This way the scripts get loaded before the elements.. and that means everything is smooth.
Though I have no idea what happens, if the displayElements option is set lower, then the actual elements count inside the list. Best avoid such situations.
Also if you noticed that the elements get floated together in CSS. You could also use display: inline-block;, but inline-block isn't very crossbrowser, so I used float. This however means, that under the elements you should have clear: both; in some form.. Or maybe even some wrapper around the list.
http://jsfiddle.net/MbQrw/
This should cover the basic stuff you're needing. It's not very elegant and stuff like initialization is missing, but the main technique is shown.
http://jsfiddle.net/rkw79/VETmf/
The concept is similar: grab an element in a list, do an action, move onto the next element, and if it is the end; loop back to the beginning.
$('input').click(function (e) {
toggleImg($('div img:first'));
});
function toggleImg(I) {
var nextI = I.next();
if (nextI.length == 0) nextI = $('div img:first');
I.toggle('slow', function() {
toggleImg(nextI);
});
}
Now this doesn't pre-populate the divs with images and it doesn't handle getting the link code in with the images as they display but you can handle that with just a little extra work.
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script>
<script>
var maxDisplay = 4;
var displayBox;
$(document).ready(function() {
StartShow();
});
function StartShow() {
var interval = 5000;
var slideShowID;
slideShowID = setInterval(Gallery, interval);
}
function Gallery() {
var nextImage = $("#container li.selected").next().length;
displayBox = Math.floor(Math.random() * maxDisplay);
if (nextImage > 0){
$("#container li.selected").removeClass("selected").next().addClass("selected");
imgSrc = $("#container li.selected").children().attr("src");
if(imgSrc != null) {
$("#" + displayBox).fadeOut('slow', function() { $("#" + displayBox).css("background-image", imgSrc); }).fadeIn();
}
}
else {
$("#container li.selected").removeClass("selected").siblings(':first').addClass("selected");
imgSrc = $("#container li.selected").children().attr("src");
if (imgSrc != null) {
$("#" + displayBox).fadeOut('slow', function() { $("#" + displayBox).css("background-image", imgSrc); }).fadeIn();
}
}
}
</script>
</head>
<body>
<ul id="container" style="display: none;">
<li class="thumbnail selected"> <img src="1.jpg"/> </li>
<li class="thumbnail"> <img src="2.jpg"/> </li>
<li class="thumbnail"> <img src="3.jpg"/> </li>
<li class="thumbnail"> <img src="4.jpg"/> </li>
<li class="thumbnail"> <img src="5.jpg"/> </li>
<li class="thumbnail"> <img src="6.jpg"/> </li>
<li class="thumbnail"> <img src="7.jpg"/> </li>
<li class="thumbnail"> <img src="8.jpg"/> </li>
<li class="thumbnail"> <img src="9.jpg"/> </li>
</ul>
<div>
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
</div>
</body>
</html>
So I have a jsFiddle with much more in the way of settings but i'm only posting the sinmplest part of the code here. I didn't use images just <li> elements with background colours.
var floor = Math.floor;
var random = Math.random;
function randomindex(num, style) {
return floor(random() * num);
};
$.fn.continuousFade = function(options) {
var settings = $.extend({
"max_visible": 4,
"delay": 2000, // in ms.
"speed": 500, // in ms.
"style": "normal"
}, options);
var children = this.children(".thumbnail").css("display", "");
for (var i = 0; i < settings.max_visible; i++) {
children.eq(i).css("display", "inline-block");
}
function fadeone() {
var visibleChild = this.children(".thumbnail:visible").eq(randomindex());
var hiddenChild = this.children(".thumbnail:not(:visible)").first();
var parent = this;
visibleChild.before(hiddenChild);
hiddenChild.css({
"position": "absolute",
"opacity": 0,
"display": "inline-block"
}).animate({
opacity: 1
}, settings.speed, function() {
hiddenChild.css("position", "");
parent.append(visibleChild.css("display", "")); // Need to put this one at the end so it will get displayed again last.
});
setTimeout(function() {
fadeone.call(parent);
}, settings.delay);
}
fadeone.call(this);
};
The jsFiddle has options for other ways of getting a random image and the ability to change the settings and it shows more children.
Current jsfiddle:- http://jsfiddle.net/Nft5a/42/
It's been a while, but maybe this will work for your defining # of images problem:
what I would do involves doing a bit of math, but say I want 4 pictures showing at all times, and they are 50px each with no margin or padding (margins and padding is where the math really comes into play) then I would put them in a div that is 200px wide (4*50) with overflow set to hidden in the html (where your list should be with the images). this is explained a bit more in this question: "http://web.enavu.com/tutorials/making-an-infinite-jquery-carousel/"
hope that helps.

If statement involving this.indexof in order to animate an element not working

I have checked many of other questions involving issues like this, but none have helped.
I'm very new to this so bare with my obvious lack of knowledge.
I was trying to create a navigation where once mouseenter on the navigation link itself, the nav link will be animated to rise up by 5px and a box of the same width would drop down to meet it in the middle. I can think of a way to do it but it will involve a lot more code than if i could use an if statement instead.
<div id="header" class="wrapper">
<div id="header_logo" class="header"></div>
<div id="header_main" class="header">
<div id="nav_drop_btn">
<div id="nav_drop_box">
<span id="1" class="nav_drop"></span>
<span id="2" class="nav_drop"></span>
<span id="3" class="nav_drop"></span>
<span id="4" class="nav_drop"></span>
</div>
<span class="nav_btn">Home</span>
<span class="nav_btn">About</span>
<span class="nav_btn">Contact</span>
<span class="nav_btn">Portfolio</span>
</div>
$(".nav_btn").mouseenter(function(){
$(this).animate({height:"25px",bottom:"0px"},400);
if (this.indexOf("home") >=-1){$("#1").animate({height:"50px"})};
});
.nav_btn is the class for all of the navigation links. home is the navigation button in question.
I am pretty sure i have done this all wrong. so would very much appreciate if someone could help me to understand what is wrong with the If statement. the rest of my code works its just this.
home is text within the <span> for .nav_id, im trying to distinguish between which .nav_btn has been clicked to then activate another line of code to animate the corresponding top bar which comes down to meet it, this top bar containing an image for that particular navigation link
this does not represent a string value. If you're looking for a value to search with indexOf, and it's a link, you'll probably want to use this.href.indexOf instead.
Test
Test 2
$('a').mouseenter(function(){
console.log(this.href.indexOf('/home'));
if (this.href.indexOf('/home') !== -1) {
console.log('Mouse enter home');
}
});
http://jsfiddle.net/kwPm6/
And you can use jQuery's .text() if you want to search the link's visible text node value:
Test
Other
$('a').mouseenter(function(){
console.log($(this).text().indexOf('Test'));
if ($(this).text().indexOf('Test') !== -1) {
console.log('Mouse enter home');
}
});
http://jsfiddle.net/gJCp8/
And with SPAN's:
<span>Test</span>
<span>Other</span>
$('span').mouseenter(function(){
console.log($(this).text().indexOf('Test'));
if ($(this).text().indexOf('Test') !== -1) {
console.log('Mouse enter home');
}
});
http://jsfiddle.net/gJCp8/1/
And as the other answer from N.G. suggests, you need to test for something NOT equal to -1, and additionally you might consider using .toLowerCase().indexOf('home') to normalize the string test value and search value casing.
To wit, just looking at your code and making these adjustments, I come up with this:
$(".nav_btn").mouseenter(function(){
$(this).animate({height:"25px",bottom:"0px"},400);
if ($(this).text().toLowerCase().indexOf("home") !== -1){
$("#1").animate({height:"50px"});
}
});
indexOf is not the correct function to use for this. You could give the home button a special class/id to allow it to behave differently on mouseenter.
$(".nav_btn").mouseenter(function(){
$(this).animate({height:"25px",bottom:"0px"},400);
});
$("#home").mouseenter(function() {
$(this).animate({height:"50px"});
});
Your indexOf is checking against >= -1
This will always be true. -1 is the value returned if the search string is not found.
Perhaps you mean to check: if (this.indexOf("home") > -1)
instead?

Categories