A cookie is text data. So you can store the id(s) and/or display state(s) of your element(s) in one or more cookies. To figure out the most efficient method we need to know how many elements on the page could be toggled, and what their default (hard coded) display state(s) are, and if there's any unifying selector or parent element for them. But something very generic and less efficient can be written.
Ready made functions to set and read cookies will come in handy. Other cookie functions might also be useful. There are at least several such functions already available around the web. here are mine:
http://www.dynamicdrive.com/forums/blog.php?b=32
Also it's good to know that all browsers that accept cookies will run a function onunload if there is one to set them. All but Opera. And that the onunload function is required for efficiency in some browsers. So we have to branch for Opera. Or ignore it.
So we could have:
Code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="one">One</div>
<div id="two">Two</div>
<a href="javascript:ReverseDisplay('one')">Toggle One On/Off</a>
<a href="javascript:ReverseDisplay('two')">Toggle Two On/Off</a>
<script type="text/javascript">
function HideContent(d) {
document.getElementById(d).style.display = "none";
cook.els[d] = 'none';
if(window.opera){cook.gather();}
}
function ShowContent(d) {
document.getElementById(d).style.display = "block";
cook.els[d] = 'block';
if(window.opera){cook.gather();}
}
function ReverseDisplay(d) {
if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; cook.els[d] = 'block'; }
else { document.getElementById(d).style.display = "none"; cook.els[d] = 'none'; }
if(window.opera){cook.gather();}
}
var cook = {
set: function(n, v, d){ // cook.set takes (name, value, optional_persist_days) - defaults to session if no days specified
if(d){var dt = new Date();
dt.setDate(dt.getDate() + d);
d = '; expires=' + dt.toGMTString();}
document.cookie = n + '=' + escape(v) + (d || '') + '; path=/';
},
get: function(n){ // cook.get takes (name)
var c = document.cookie.match('(^|;)\x20*' + n + '=([^;]*)');
return c? unescape(c[2]) : null;
},
kill: function(n){ // cook.kill takes (name)
cook.set(n, '', -1);
},
killall: function(){ // cook.killall takes no parameters
var cookies = document.cookie.split(';'), i = cookies.length - 1;
for (i; i > -1; --i){
cook.kill(cookies[i].split('=')[0]);
}
},
els: {},
gather: function(){
var ar = [], p;
for(p in cook.els){
ar.push(p + ':' + cook.els[p]);
}
if(ar.length){
cook.set('the_elements', ar.join(','));
}
}
};
if(!window.opera){onunload = cook.gather;}
;(function(){
var str = cook.get('the_elements'), ar = [], el, the_el;
if(str){
ar = str.split(',');
for (var i = ar.length - 1; i > -1; --i){
el = ar[i].split(':');
if((the_el = document.getElementById(el[0]))){
the_el.style.display = el[1];
cook.els[el[0]] = el[1];
}
}
}
})();
</script>
</body>
</html>
There are a number of things I don't like about that code, still not perfect, but getting better:
Code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div><a href="javascript:ReverseDisplay('one');">Toggle One On/Off</a></div>
<div id="one">One</div>
<div><a href="javascript:ReverseDisplay('two');">Toggle Two On/Off</a></div>
<div id="two">Two</div>
<script type="text/javascript">
;(function(){
var displayers = {
HideContent: function(d) {
document.getElementById(d).style.display = "none";
cook.els[d] = 'none';
if(window.opera){cook.gather();}
},
ShowContent: function(d) {
document.getElementById(d).style.display = "block";
cook.els[d] = 'block';
if(window.opera){cook.gather();}
},
ReverseDisplay: function(d) {
if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; cook.els[d] = 'block'; }
else { document.getElementById(d).style.display = "none"; cook.els[d] = 'none'; }
if(window.opera){cook.gather();}
}
};
var cook = {
set: function(n, v, d){ // cook.set takes (name, value, optional_persist_days) - defaults to session if no days specified
if(d){var dt = new Date();
dt.setDate(dt.getDate() + d);
d = '; expires=' + dt.toGMTString();}
document.cookie = n + '=' + escape(v) + (d || '') + '; path=/';
},
get: function(n){ // cook.get takes (name)
var c = document.cookie.match('(^|;)\x20*' + n + '=([^;]*)');
return c? unescape(c[2]) : null;
},
kill: function(n){ // cook.kill takes (name)
cook.set(n, '', -1);
},
killall: function(){ // cook.killall takes no parameters
var cookies = document.cookie.split(';'), i = cookies.length - 1;
for (i; i > -1; --i){
cook.kill(cookies[i].split('=')[0]);
}
},
els: {},
gather: function(){
var ar = [], p;
for(p in cook.els){
ar.push(p + ':' + cook.els[p]);
}
if(ar.length){
cook.set('the_elements', ar.join(','));
}
},
addEvent: (function(){return window.addEventListener? function(el, ev, f){
el.addEventListener(ev, f, false);
}:window.attachEvent? function(el, ev, f){
el.attachEvent('on' + ev, f);
}:function(){return;};
})()
};
if(!window.opera){cook.addEvent(window, 'unload', cook.gather);}
var a = document.getElementsByTagName('a'), re = /(ShowContent|HideContent|ReverseDisplay)\('(.+)'\)/, func, i;
for (i = a.length - 1; i > -1; --i){
if((func = re.exec(a[i].href))){
(function(el, func){
cook.addEvent(el, 'click', function(e){
e = e || event;
if(e.preventDefault){e.preventDefault();}
e.returnValue = false;
displayers[func[1]](func[2]);
return false;
});
})(a[i], func);
}
}
var str = cook.get('the_elements'), ar = [], el, the_el;
if(str){
ar = str.split(',');
for (i = ar.length - 1; i > -1; --i){
el = ar[i].split(':');
if((the_el = document.getElementById(el[0]))){
the_el.style.display = el[1];
cook.els[el[0]] = el[1];
}
}
}
})();
</script>
</body>
</html>
Bookmarks