I want to be able to hide and unhide a lengthy menu with a button click, and that I have been able to do. But I don't want visitors to have to hide the menu every time they visit a new page, so I would like their last click to be remembered. This I have not been able to do. Any help is appreciated. I am even open to a better way to do this.
The code I thought would work, but doesn't, is:
$(document).ready(function(){
$("button").click(function(){
$("div.themenu").toggle(100);
});
});
$(function(){
if($.cookie){
$("#themenu").toggle(!(!!$.cookie("toggle-state")) || $.cookie("toggle-state") === 'true');
}
$('#menubutton').on('click', function(){
$("#themenu").toggle();
$.cookie("toggle-state", $("#themenu").is(':visible'), {expires: 1, path:'/'});
});
});
The code for the button they click is:
<button id="menubutton" class="myButton">Show / Hide Menu</button>
And the long, long menu is shown like this:
<div class="themenu">Long Long Menu Code</div>
Just for fun: here's an alternative solution which doesn't require a cookie, but sets a URL parameter:
//on page load
if (location.href.match('menu=show'))
$("#themenu").toggle();
//for every link click, block & redirect with menu=show if menu is visible
$(document.body).on('mousedown', 'a', function(e) {
e.preventDefault();
var menuParam = (location.href.match('?') ? '&' : '?') + 'menu=show';
location.href = $("#themenu").is(':visible') ? this.href + menuParam: this.href;
});
localStorage is a good place to store this kind of state. Setting is as easy as localStorage.menu = 'hidden' or localStorage.menu = 'visible', checking can be done with (localStorage && localStorage.menu==='hidden'). People with REALLY old browsers won't get the feature but that's a very small slice of users. This setting will live across visits to the site but only in the same browser. There is an issue with some browsers in 'private browsing' mode. They sometimes make localStorage cause an error when modified.
Related
I've spent quite a while trying to find answers for this issue, but haven't had any success. Basically I need to scroll the user to the contact portion of the website when they go to healthdollars.com/#contact. This works just fine in Safari, but in Chrome I haven't had any luck. I've tried using jQuery/Javascript to force the browser to scroll down, but I haven't been able to.
Does anyone have any ideas? It's driving me crazy - especially since it's such a simple thing to do.
Not a full answer but in Chrome if you disable Javascript I believe you get the desired behavior. This makes me believe that something in your JavaScript is preventing default browser behavior.
It looks to me like the target element doesn't exist when when page first loads. I don't have any problem if I navigate to the page and then add the hash.
if (window.location.hash.length && $(location.hash)) {
window.scrollTo(0, $(location.hash).offset().top)
}
check for a hash, find the element's page offset, and scroll there (x, y).
edit: I noticed that, in fact, the page starts at #contact, then scrolls back to the top. I agree with the other answerer that there's something on your page that's scrolling you to the top. I'd search for that before adding a hack.
You can do this with JS, for example` if you have JQuery.
$(function(){
// get the selector to scroll (#contact)
var $to = $(window.location.hash);
// jquery animate
$('html'/* or body */).animate({ scrollTop: $to.offset().top });
});
The name attribute doesn't exists in HTML 5 so chrome looks to have made the name attribute obsolete when you use the DOCTYPE html.
The other browsers have yet to catch up.
Change
<a name="contact"></a>
to
<a id="contact"></a>
Maybe this workaround with vanilla javascript can be useful:
// Get the HTMLElement that you want to scroll to.
var element = document.querySelector('#contact');
// Stories the height of element in the page.
var elementHeight = element.scrollHeight;
// Get the HTMLElement that will fire the scroll on{event}.
var trigger = document.querySelector('[href="#contact"]');
trigger.addEventListener('click', function (event) {
// Hide the hash from URL.
event.preventDefault();
// Call the scrollTo(width, height) method of window, for example.
window.scrollTo(0, elementHeight);
})
What I am trying to do is have four links that each will display and hide a certain div when clicked. I am using slideToggle and I was able to get it to work with really sloppy and repetitive code. A friend of mine gave me a script he used and I tried it out and finally was able to get something to happen. However, all it does is hide the div and wont redisplay. Also it hides all the divs instead of just the specific one. Here is a jsfiddle I made. Hopefully you guys can understand what I am trying to do and help! Thanks alot.
Here is the script I'm using.
$(document).ready(function () {
$(".click_me").on('click', function () {
var $faq = $(this).next(".hide_div");
$faq.slideToggle();
$(".hide_div").not($faq).slideUp();
});
});
http://jsfiddle.net/uo15brz1/
Here's a link to a fiddle. http://jsfiddle.net/uo15brz1/7/
I changed your markup a little, adding id attributes to your divs. The jquery, gets the name attribute from the link that's clicked, adds a # to the front, hides the visible div, then toggles the respective div. I also added e.preventDefault to stop the browser from navigating due to the hash change. As an aside, javascript don't require the $ prefix.
$(document).ready(function () {
$(".click_me").on('click', function (e) {
e.preventDefault();
var name = $(this).attr('name');
var target = $("#" + name);
if(target.is(':visible')){
return false; //ignore the click if div is visible
}
target.insertBefore('.hide_div:eq(0)'); //put this item above other .hide_div elments, makes the animation prettier imo
$('.hide_div').slideUp(); //hide all divs on link click
target.slideDown(); // show the clicked one
});
});
Welcome to Stack Overflow!
Here's a fiddle:
http://jsfiddle.net/uo15brz1/2/
Basically, you need a way to point to the relevant content <div> based on the link that's clicked. It would be tricky to do that in a robust way with your current markup, so I've edited it. The examples in the jquery documentation are pretty good. Spend some time studying them, they are a great way to start out.
I have a javascript/jQuery cookie confirmation box on my site as shown here: http://jsfiddle.net/x7rAk/1/
var checkCookies = document.cookie;
var cookieNotice = '<div id="continue_box" class="cookie_box"><p>This website uses cookies to improve the user experience. For more information on cookies please see this link. By clicking continue, you agree to the use of cookies.</p><p class="cookies_accept"><span class="cookie_button" id="continue"><img src="/images/tick.png"/><span> Continue</span></span></p></div>';
$('body').ready(function() {
$('body').prepend($(cookieNotice).fadeIn(2000));
});
var continueButton = 'span#continue.cookie_button';
var closeButton = 'span#close.cookie_button';
var closeNotice = '<div id="close_box" class="cookie_box" style="display:none"><p>You have agreed to the use of cookies. This allows us to bring you a better service by remembering your preferences.</p><p class="cookies_accept"><span class="cookie_button" id="close"><img src="/images/cross.png"/><span> Close</span></span></p></div>';
$('#continue_box.cookie_box').ready(function() {
$(continueButton).click(function() {
$('#continue_box.cookie_box').fadeOut(1000, function() {
$('body').prepend($(closeNotice).fadeIn(1000));
});
});
});
$(closeButton).click(function() {
$('#close_box.cookie_box').fadeOut(2000);
});
This is missing images and fonts etc. but it works exactly the same as on my site.
If you run the code, you will see that the box doesn't disappear when you click close.
First of all, how do I fix it, and secondly why does mine not work (I like to know why so I don't have to waste your time again :) ).
Thank you,
Connor
P.S. On my site it checks whether you have a cookie called cookiesAgree before showing it so the code is normally more sophisticated.
This should work
$(document).on("click", closeButton, function() {
$('#close_box.cookie_box').fadeOut(2000);
});
The content is being added dynamically, so you need to register the event handler.
So long story short im working on a web app and using AJAX within it.
I'm trying to disable the default actions of links when clicked, attach a hash value to the link and then remove the "#" from the url.
the problem im having is that, although the hash values are being attached accordingly, the substring method isnt extracting the "#", it extracts the letter after it.....
here is my code. PS, i left my comments inthere so you get where im trying to go with this
so i dont know....my logic or setup may be wrong....
$(document).ready(function(){
//app vars
var mainHash = "index";
var menuBtn = $('.leftButton');
//~~~~~~load the index page at first go.
loadPage();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~menu show/hide
menuBtn.click( function(){
$('#menu').toggleClass();
});
//Menu items on click , disable link default actions.
$('#menu a').click( hijackLinks );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~functions for mobile index load AND hijacking app links to AJAX links.
function loadPage(url){
if( url == undefined){
$('#contentHere').load('index.html #content', hijackLinks);
window.location.hash = mainHash;
} else {
$('#contentHere').load(url + '#content', hijackLinks );
}
}
function hijackLinks(e){
var url = e.target.href;
e.preventDefault();
loadPage(e.target.href);
window.location.hash = $(this).attr("href").substring(1);
}
});
what im wanting is to remove the "#" from the url. What am i doing wrong, what am i not seeing/understanding?
ive tried substring/substr etc and both do the same thing in that no matter what numbers i choose to insert into the substrings params, they remove EVERYTHING BUT the "#" lol....
Thanks in advanced.
Well, you don't really change the link itself, you only change the window.location.hash, and the hash always has a "#" at the beginning.
What you need to do in order to change the entire url (and remove the '#') is to manipulate the browser history.
Although you should know it works only in newer browsers (the exact browser versions are in the link), so if you target your website to older too browsers you might need to think about having a fallback using the hash. If you decide to have such a fallback, I suggest searching for a plugin which does it instead of making it all yourself.
I am pretty new to Javascript so please bear with me.
$('#bioContent').css('display','none');
$('#skillsContent').css('display','none');
$('#credsTab').css('background-color','#fff');
$('#credsTab a').css('color','#19d700');
$('#bioTab').css('background-color','#ccc');
$('#bioTab a').css('color','#444');
$('#skillsTab').css('background-color','#ccc');
$('#skillsTab a').css('color','#444');
$('#credsTab').click(function(){
$('#credsContent').css('display','block');
$('#bioContent').css('display','none');
$('#skillsContent').css('display','none');
$('#credsTab').css('background-color','#fff');
$('#credsTab a').css('color','#19d700');
$('#bioTab').css('background-color','#ccc');
$('#bioTab a').css('color','#444');
$('#skillsTab').css('background-color','#ccc');
$('#skillsTab a').css('color','#444');
})
$('#bioTab').click(function(){
$('#bioContent').css('display','block');
$('#credsContent').css('display','none');
$('#skillsContent').css('display','none');
$('#bioTab').css('background-color','#fff');
$('#bioTab a').css('color','#19d700');
$('#credsTab').css('background-color','#ccc');
$('#credsTab a').css('color','#444');
$('#skillsTab').css('background-color','#ccc');
$('#skillsTab a').css('color','#444');
})
$('#skillsTab').click(function(){
$('#skillsContent').css('display','block');
$('#bioContent').css('display','none');
$('#credsContent').css('display','none');
$('#skillsTab').css('background-color','#fff');
$('#skillsTab a').css('color','#19d700');
$('#bioTab').css('background-color','#ccc');
$('#bioTab a').css('color','#444');
$('#credsTab').css('background-color','#ccc');
$('#credsTab a').css('color','#444');
})
That's my javascript implementation of tabs. Basically on click, divs hide away and others appear.
My problem with this is that on the skillsTab, there's an add skills method, and when I click on that, it refreshes the page, and when it does, it brings me back to the credsTab, the default when the page is loaded.
I was wondering if that's a way so that when it refreshes, it will stay on the skillsTab.
Keep state around, which can be done via fragment URLs or HTML5 history.
e.g., make opening up the skills tab change the fragment to #skills, which will remain across a refresh. Then check window.location.hash in your onLoad to determine what initial state your page should be in.
function switchToTab(tabName) {
// DOM/CSS manipulation etc. here
}
var tabs = ['bio', 'skills', 'creds'];
var initialTab = 'bio';
for (var i = 0; i < tabs.length; i++) {
(function(tabName) {
document.getElementById(tabName + 'Tab').addEventListener('click', function() {
switchToTab(tabName);
location.hash = '#' + tabName;
}, false);
})(tabs[i]);
}
window.addEventListener('load', function() {
if (location.hash[0] == '#')
switchToTab(location.hash.substr(1));
}, false);
window.addEventListener('hashchange', function() {
if (location.hash[0] == '#')
switchToTab(location.hash.substr(1));
else
switchToTab(initialTab);
}, false);
Untested, and there's plenty of JS libraries out there that abstract this away for you.
An initial suggestion. give all your tabs the same class, maybe class='toggleableTab' then you can use
$('.togglableTab').live('click',function(){
$('.togglableTab').not(this).hide();
$(this).show();
});
as for the page refresh. Look into using AJAX to "add" your skills live on the page without a full page refresh.
There are several tabbed solutions already in place that you could make use of - for example, http://jqueryui.com/demos/tabs/. JQuery UI is a great way to have a lot of this work done for you.
If you want to do it yourself, I would also suggest a solution using classes, but slightly different than other suggestions. Instead, have two classes, "activeTab" and "tabbable". In your css, define "activeTab" as visible, and "tabbable" as hidden. Give each tab an ID and the class of "tabbable". Have a hidden field in your form called "activeTabId". Make sure that this gets passed back from the server side when you load the page, including setting it to the default tab when you first load the page. You could then run the following code on page load to make it all play well together:
$(".tabbable").click(new function(){
$(".tabbable").removeClass("activeTab");
$(this).addClass("activeTab");
$("#activeTabId").val($(this).attr("id"));
});
$("#" + $("#activeTabId").val()).addClass("activeTab");