Store div status on page reload - javascript

I have multiple divs in one html page under common wrapper class.
I am using hide and show method on clicking next and previous option.
What I am trying to achieve: On page reload/refresh, the div which is showing currently should show after page reload.
So in short if you reload/refresh from pink screen, it should show same pink screen after page reload.
What I tried: I am storing the display properties (none or block) is local storage and on page reload trying to give same properties to divs again. Most of the responses and solution I checked in Stack overflow is regarding opening the same tab when refresh. but my case is what in same tab I have multiple div and I want to open from the same state which it was earlier.
Logic I used:
$(window).on('load', function(){
var disp = localStorage.getItem("disp");
var ustatus = JSON.parse(disp);
$(".chk").text(ustatus);
for (var x=ustatus; x<ustatus.length; x++){
$(".pg"+x).css("display", ustatus[x]);
}
});
This is fiddle link I tried:
Page reload demo JS Fiddle link

Your HTML and CSS code is perfect but you need to make corrections in your JavaScript code.
Observation 1 : You "for" loop to assign display style has problem with variable x. You need to assign integer value to x.
Observation 2 : You need to remove that "display" style from "div" elements when you click on "next" and "previous" links.
Hear is new Js fiddle link with updated code.
$(window).on('load', function () {
//localStorage.removeItem("disp");
var disp = localStorage.getItem("disp");
var ustatus = JSON.parse(disp);
$(".chk").text(ustatus);
for (var x = 1; x <= ustatus.length; x++) {
$(".pg" + x).css("display", ustatus[x-1]);
}
});
$(".next").on("click", function () {
$(this).parent().addClass("off").removeClass("on").removeAttr("style");
$(this).parent().next().addClass("on").removeClass("off").removeAttr("style");
});
$(".prev").on("click", function () {
$(this).parent().addClass("off").removeClass("on").removeAttr("style");
$(this).parent().prev().addClass("on").removeClass("off").removeAttr("style");
});
$(window).on('beforeunload', function () {
var display = $(".clr").map(function () {
return $(this).css("display");
}).get();
localStorage.setItem("disp", JSON.stringify(display));
});
You can also download this file. Please run index.html to see the output.

You don't really need the on class:
$(window).on('load', function(){
var disp = localStorage.getItem("disp");
var ustatus = JSON.parse(disp);
$(".chk").text(ustatus);
for (var x=0; x<ustatus.length; x++){
$(".pg"+(x+1)).toggleClass("off", ustatus[x]);
}
});
$(".next").on("click", function(){
$(this).parent().addClass("off");
$(this).parent().next().removeClass("off");
});
$(".prev").on("click", function(){
$(this).parent().addClass("off");
$(this).parent().prev().removeClass("off");
});
$(window).on('beforeunload', function(){
var display = $(".clr").map(function(){
return $(this).hasClass("off");
}).get();
localStorage.setItem("disp", JSON.stringify(display));
});
Fiddle
note: you can't use $(window).on('load', ...) in a fiddle - the JS in the editor is run on load
EDIT: you might also want to validate ustatus before applying it, something like
if (Array.isArray(ustatus) && ustatus.filter(x => x === true).length === 1) {
for (var x=0; x<ustatus.length; x++){
$(".pg"+(x+1)).toggleClass("off", ustatus[x]);
}
}

You can do it without using display, you can use on and off classes, i think that's why they are created for
$(window).on('load', function(){
var disp = localStorage.getItem("disp");
var ustatus = JSON.parse(disp);
if(ustatus!=undefined){
$(".chk").text(ustatus);
for (var x=1; x<=ustatus.length; x++){
if(ustatus[x-1]=='on'){
$(".pg"+x).addClass("on").removeClass("off");
}
else{
$(".pg"+x).addClass("off").removeClass("on");
}
}
}
$(".next").on("click", function(){
$(this).parent().addClass("off").removeClass("on");
$(this).parent().next().addClass("on").removeClass("off");
});
$(".prev").on("click", function(){
$(this).parent().addClass("off").removeClass("on");
$(this).parent().prev().addClass("on").removeClass("off");
});
$(window).on('beforeunload', function(){
var display = $(".clr").map(function(){
if($(this).hasClass('on'))
return 'on';
else
return 'off';
}).get();
localStorage.setItem("disp", JSON.stringify(display));
});
});

Related

Have a JS function *constantly* listen for clicks?

This seems like something that should be really simple. I have a few images animating on a page, but I want the user to be able to click on any one of them at any time and then go to a related page.
Problem is, evidently clicks stopped being listened for at some point if I use a loop to search through an array of clickable items. I thought having a function separate from the one that handles the animation would allow it to constantly listen no matter what the animated images were doing, but it seems once the "complete" function is called (for the "animate" function), the function that is listening for clicks (wholly separate from the animation, and using setInterval to listen for clicks) stops listening.
Oddly enough, I believe I did not have this problem when just listening for "img" instead of an array of different images.
Ideas as to what I'm doing wrong? More info needed? I tried to remove any irrelevant code below.
var links = ["#portfolio", "#animations", "#games"];
$(function() {
setInterval(function(){
for (var i=0; i<links.length; i++) {
$(links[i]).click(function(){
window.location.replace("http://www.gog.com");
});
}
}, 500);
});
$(document).ready(function() {
links.forEach(function(current){
//various vars
var link = $(current);
var footer3 = $(".footer3");
var over = true;
var randomTime = 3000*(Math.random()+1);
//dust vars
...
//image vars
var imageUrlShadow = 'images/home/non-char/shadow-pngs/shadow';
var imageUrlCharacter = 'images/home/char-pngs/';
var portfolioSrc;
var animationsSrc;
var gamesSrc;
//animate the characters
link.animate({
top: '0'
}, {
duration: randomTime,
easing: 'easeOutBounce',
step: function(now, tween) {
/*handle shadows*/
...
/*handle characters*/
if (now < -25 && over == false) {
...
} else if (now >= -25) {
...
}
$("#"+ link.data("portfolio")).attr('src', portfolioSrc);
$("#"+ link.data("animations")).attr('src', animationsSrc);
$("#"+ link.data("games")).attr('src', gamesSrc);
/*handle dust*/
var dustDoneMoving = '-50px';
var dustNotMoving = '0px';
//if link is NOT touching footer3
...
//set to "sitting" images when animation is done
complete: function() {
...
setTimeout(function() {
...
}, 1000);
}
})
})
});
var links = ["#portfolio", "#animations", "#games"];
$(function() {
$(links.join(',')).click(function(){
window.location.replace("http://www.gog.com");
});
});
One time only and listener will be attached to the image.
Consider listening via window
var links = ["#portfolio", "#animations", "#games"];
$(window).on('click', links.join(', '), function() {
// do what you wanna
});
I apologize, it turns out that, apparently, the problem was related to the z-index. There were some other divs with 0 opacity "covering up" the array divs.
Setting the z-index to 2 for the array items has fixed the matter. Again, my apologies.
I have modified your code. See, if this works now.
I have added one more array which contains some URLs. So, the intention is that on click of a particular element, its respective URL should be opened.
So, the sequence in these array will matter with respect to each other.
Also, I have made use of 'on', so that 'click' event should be handled even during animation.
var links = ["#portfolio", "#animations", "#games"];
var sites = ["http://www.gog.com", "http://www.gog1.com", "http://www.gog2.com"]; //change these to the expected URLs
$(function() {
for (var i=0; i<links.length; i++) {
$(document ).on("click",links[i],function(){
window.location.replace(sites[i]);
});
}
});

Get image ids in a div every second

I was successful in getting the id of all images within a div when clicking the div with the following codes below:
<script type="text/javascript">
function getimgid(){
var elems = [].slice.call( document.getElementById("card") );
elems.forEach( function( elem ){
elem.onclick = function(){
var arr = [], imgs = [].slice.call( elem.getElementsByTagName("img") );
if(imgs.length){
imgs.forEach( function( img ){
var attrID = img.id;
arr.push(attrID);
alert(arr);
});
} else {
alert("No images found.");
}
};
});
}
</script>
The codes above works perfectly, doing an alert message of the image id when clicking card div. Now what I want is to run this function without clicking the div in every 5 seconds. I have tried setInterval (getimgid, 5000), but it doesn't work. Which part of the codes above should I modify to call the function without clicking the div. Any help would be much appreciated.
JSFiddle
You should be calling it this way:
setInterval (function(){
getimgid();
},5000);
also remove binding of click event for element.
Working Fiddle
Use elem.click() to trigger click
function getimgid() {
var elems = [].slice.call(document.getElementsByClassName("card"));
elems.forEach(function (elem) {
elem.onclick = function () {
var arr = [],
imgs = [].slice.call(elem.getElementsByTagName("img"));
if (imgs.length) {
imgs.forEach(function (img) {
var attrID = img.id;
arr.push(attrID);
alert(arr);
});
} else {
alert("No images found.");
}
};
elem.click();
});
}
setInterval(getimgid, 1000);
DEMO
Problem: You are not triggering the click in setInterval. You are only re-running the event binding every 5 secs.
Solution: Set Interval on another function which triggers the click. Or remove the click binding altogether if you don't want to manually click at all.
Updated fiddle: http://jsfiddle.net/abhitalks/3Dx4w/5/
JS:
var t;
function trigger() {
var elems = [].slice.call(document.getElementsByClassName("card"));
elems.forEach(function (elem) {
elem.onclick();
});
}
t = setInterval(trigger, 5000);

.slideToggle nested ajax repeater

I have a function that writes out to a cooke the value of the DIV that holds that data that I want to show, the cookie code works, the toggle code works but when the page refreshses, I can get the list of repeater elements, itterate through them, determine if the section should be hidden or not but I can't use visible, I can't use .show() or .hide(), I know this has to be easy but what am I over looking???
This is my working code for the slidetoggle that works and writes the true or false to the cooke based on the repeater title attribute:
$(document).ready(function () {
$("a.toggle").click(function () {
var inObj = $(this).parent().find('div#fader');
var inTitle = inObj.attr('title');
inObj.slideToggle('fast', function () {
docCookies.setItem(inTitle, inObj.is(':visible').toString());
});
});
});
This is the code block that I have the problem with, specifically, the .show() and the .hide() are not known methods, so I have the object in inObj[] collection, I am not sure how to cast this or deal with this in javascript.....
$(window).load(function () {
var inObj = $('div#fader');
for (var i = 0; i < inObj.length; i++) {
var objTitle = inObj[i].title;
var item = docCookies.getItem(objTitle);
if (item == "true") {
inObj[i].show();
}
else {
inObj[i].hide();
}
}
});
Use $(inObj[i]).show() and $(inObj[i]).hide().

If var not set always results in true, even if its set

Not sure how to formulate this but here it goes.
I am checking if a var exists (content), if it doesnt i set it.
Problem is next click, it still behaves as if there is no var content. But why??
Here my code:
$("#nav a").click(function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content)
{
var content = $('<div>').load(load);
$(".content").append(content);
}
else
{
var position = content.offset();
$(document).scrollTop(position);
}
});
It never results to else, so always a click is made the whole load and append function repeats.
Basically how can I record that content for this particular link has been loaded once, so the else function should be performed next time?
Also, what is wrong with my if(!content) statement? Is it because of scope?
In Javascript functions determine the scope of an object. You need to place content in the global scope. Currently it is created within the anonymous function assigned to the click event handler, so when the function is executed again content is out of scope causing it to return false.
var content;
$("#nav a").click(function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content)
{
content = $('<div>').load(load);
$(".content").append(content);
}
else
{
var position = content.offset();
$(document).scrollTop(position);
}
});
Try to make the var content as a global variable rather than a local one, like you are doing right now. That's why the if (!content) result as true always, like:
var content;
$("#nav a").click(function (event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
if (!content) {
content = $('<div>').load(load);
$(".content").append(content);
} else {
$(document).scrollTop(content.offset());
}
});
Just to show what happens, when value of content is not set at first and then set again:
var content;
console.log(content); // undefined
console.log(!content); // true
content = 'text';
console.log(content); // text
console.log(!content); // false
Thanks to everyone for answering the first question about the checking if var exists.
I ended up ditching this whole concept it turned out the
one()
function is what I needed all along. In order to only execute a function once and another function on all following clicks.
Here it is:
$(document).ready(function() {
//Ajaxify Navi
$("#nav a").one("click", function(event) {
event.preventDefault();
var href = $(this).attr("href");
var load = href + " .content";
var content = $('<div>').load(load);
$(".content").append(content);
$(this).click(function(event) {
event.preventDefault();
var position = content.offset().top;
$(document).scrollTop(position);
$("body").append(position);
});
});
});
What this is is the following:
1st click on a button loads content via ajax and appends it, second click on the same button only scrolls to said content.

need to modify this jquery pop menu script to work with ajax

I am using this script from: http://pop.seaofclouds.com/
The problem is if you call the script multiple times it causes a cascading effect of a pop-out within a pop-out for as many times as you call the script.
I'm trying to figure out how to prevent it from executing when the popout has already been set. Here's the script:
//
// pop! for jQuery
// v0.2 requires jQuery v1.2 or later
//
// Licensed under the MIT:
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright 2007,2008 SEAOFCLOUDS [http://seaofclouds.com]
//
(function($) {
$.pop = function(options){
// inject html wrapper
function initpops (){
$(".pop").each(function() {
var pop_classes = $(this).attr("class");
if ( $(this).find('.pop_menu').length) {
// do nothing
} else {
$(this).addClass("pop_menu");
$(this).wrap("<div class='"+pop_classes+"'></div>");
$(".pop_menu").attr("class", "pop_menu");
$(this).before(" \
<div class='pop_toggle'></div> \
");
}
});
}
initpops();
// assign reverse z-indexes to each pop
var totalpops = $(".pop").length + 100;
$(".pop").each(function(i) {
var popzindex = totalpops - i;
$(this).css({ zIndex: popzindex });
});
// close pops if user clicks outside of pop
activePop = null;
function closeInactivePop() {
$(".pop").each(function (i) {
if ($(this).hasClass('active') && i!=activePop) {
$(this).removeClass('active');
}
});
return false;
}
$(".pop").mouseover(function() { activePop = $(".pop").index(this); });
$(".pop").mouseout(function() { activePop = null; });
$("body").on("click", ".pop", function(){
closeInactivePop();
});
// toggle that pop
$("body").on("click", ".pop_toggle", function(){
$(this).parent(".pop").toggleClass("active");
});
}
})(jQuery);
now when i load this script on an ajax call the new pop-out menus work but the old ones do not react to the onclick event.
You shouldn't mess with the plugin. It works exactly like it should.
Better show us how you call this on elements that you already have.
Also I don't like this plugin. Better use something from JqueryUI
You can do such thing in much easier way.
[edit]
I tried your first code (the plugin) and it works correctly for me.
[edit]
OK. I get it. You call $.pop(); multiple times. You shouldn't! Calling $.pop(); will pin up the drop down menu to all elements that has class="pop". This is the reason why you have such funny stack.
Just use $.pop(); once.
Plugin doesn't give ability to connect NEW elements that was dynamically created on the page.
Removed pop from ajax call and just called this on success:
$(".pop").each(function() {
var pop_classes = $(this).attr("class");
if ( $(this).find('.pop_menu').length) {
// do nothing
} else {
$(this).addClass("pop_menu");
$(this).wrap("<div class='"+pop_classes+"'></div>");
$(".pop_menu").attr("class", "pop_menu");
$(this).before(" \
<div class='pop_toggle'></div> \
");
}
});
// assign reverse z-indexes to each pop
var totalpops = $(".pop").length + 100;
$(".pop").each(function(i) {
var popzindex = totalpops - i;
$(this).css({ zIndex: popzindex });
});
// close pops if user clicks outside of pop
activePop = null;
function closeInactivePop() {
$(".pop").each(function (i) {
if ($(this).hasClass('active') && i!=activePop) {
$(this).removeClass('active');
}
});
return false;
}
$(".pop").mouseover(function() { activePop = $(".pop").index(this); });
$(".pop").mouseout(function() { activePop = null; });

Categories