Show/hide menu with jQuery - javascript

I have a page with content (on the left) and sidebar (on the right). For screen widths <= 480px the 2 div's are placed one under the other (100% widths). The "Show/Hide" button that becomes visible is meant to toggle the sidebar's visibility when clicked. I use
$(".sidebar .box").slideToggle(200);
for this purpose.
See everything together on jsfiddle.
The problem: if I switch to wide screen and then back to narrow screen (width <= 480px) again, clicking the button produces a "back and forth" bug.
Where is my mistake?
Thank you!

I believe the reason is that this code:
$("a.expander").click(function () {
$(this).toggleClass('close');
$(".sidebar .box").slideToggle(200);
});
gets executed every time the function showSidebar is run, which is every time the window is resized. JQuery's click function adds a new event handler each time, and executes all of them on each window resize.
The solution would be to move the click handler registration outside of the function.

I believe that your problem is that your slide function gets called continuously when your window is resized. Rather than have this event occur unchecked, try to control it using an event handler like so:
Use .one():
$('#your_element_id').one("click", function () {
$('.your_css_style_class').slideToggle(200);
});
Another thing to keep in mind is that if down the line, you desire to display it hidden, you may want to use .slideDown() rather than .slideToggle() to begin with.
Here is a jQuery reference to the 'one' function: http://api.jquery.com/one

something like this? http://jsfiddle.net/jqdvj42u/3/
$(document).ready(function() {
$("a.expander").click(function () {
$(this).toggleClass('close');
$(".sidebar .box").slideToggle(200);
});
});
function showSidebar() {
if ($(window).width() <= 480) {
// Close sidebar when window width <= 480px
$(".sidebar .box").removeClass('open');
// Click expander button to show/hide sidebar
} else {
$("a.expander").removeClass('close');
// Open sidebar when window width > 480px;
$(".sidebar .box").addClass('open');
}
}
showSidebar();
$(window).resize(showSidebar);
your click shouldnt be called within showSidebar() because it'll bind the click event every time that function is called. resize triggers showSidebar() multiple times, so the click is bound multiple times. also, you should use jQuery 1.11 as the lowest version since its the most up-to-date version thats stable on IE<9. if you dont mind support on IE<9, use jQuery version 2.0 or higher.

Related

slideToggle works multiple times when watching screen resize

I'm trying to apply the slideToggle function over a menu based on screen size , but this code is applying the function multiple times with just one click , tried every solution here but nothing works .
I know the problem is the click event inside a window resize, but the application should be like that, so please i need alternative solution to have a working code.
$(window).on("resize", function () {
if (screen.width < 768) {
$(".part-heading").click(function (e) {
$(this).next(".sections").slideToggle("slow");
});
}
});
You are registering multiple event listeners, one every time the screen size change. And when you click all of them will run. You can change your script as below, so check the size on each click rather than watching the resize:
$(".part-heading").click(function (e) {
if (screen.width < 768) {
$(this).next(".sections").slideToggle("slow");
}
});

Why isn't window.onresize working? (javascript/jquery)

I'm trying to make this site show a tab-box on large screens, but just a normal layout on smaller screens. Here's what I have:
function adapt() {
if(document.documentElement.clientWidth > 800) {
$(document).ready(function() {
$(".box").hide();
$(".box:first").show();
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active");
$(this).addClass("active");
$(".box").hide();
var activeTab = $(this).attr("rel");
$("#"+activeTab).show();
});
});
}else{
$(document).ready(function () {
$('.box').show();
});
};}
window.onload = adapt();
window.onresize = adapt();
The onload event handler works, so the tab-box jquery function only works if the page is loaded on a larger screen, and it shows all the content when loaded on a smaller screen. I added the onresize event so it would also change when the browser window is shrunk down, but it doesn't work. If I load on a large screen and then shrink it, all that shows is the content that was in the first tab, and if I load on a small screen, and then make the window bigger, all the content is displayed and the tab buttons don't work. Am I just misinterpreting how window.resize is supposed to work?
I'm guessing that maybe the event only fires once the first time the resize occurs, and if the difference isn't enough that time for my other conditional to take over, it doesn't happen. If this is the case, is there a way to make it continually check for screen size, like with CSS media queries?
don't forget, that if some other code in your project also uses window.onresize or window.onload - your code will be overwritten
it's a better practice to use addEventListener function
window.addEventListener('resize', adapt);
You need to call the reference, not execute the function
window.onload = adapt;
window.onresize = adapt;
Because when you do
window.onload = adapt();
window.onresize = adapt();
You execute adapt() and since it return nothing, you have nothing done on these events
You can try with jquery:
$(document).ready(function() {
adapt(); // onload
$(window).resize(adapt()); // resize
});

jQuery Click event triggers more times on every window resize

People!
This is the first time I come here to ask something, so far, always when I had a problem, I could find a good answer here. So, in first place, thanks for this amazing community!
Now let's go to the problem:
I'm doing a responsive menu that check the window.resize event and, when it fits the minimum browser width, a click function for a button is allowed. If the browser width is greater, then the click function is unbound. I need to do this because the same element that is the button on the mobile version, is a visual element on the desktop version.
The problem is that, with the code that I have now, when the page is loaded, the click function works fine. But, if I resize the browser and click on the element again, it triggers more than once the state, sometimes leaving the impression that the function isn't triggered. And, if I resize the browser again, it triggers the click function more than the last time I clicked. Really annoying.
To help understand what is happening, I've made a simple example. Here's is the simple code (just to check the click function issue):
HTML:
<ul>
<li><span class="sub-toggle">Testing 01</span></li>
<li><span class="sub-toggle">Testing 02</span></li>
<li><span class="sub-toggle">Testing 03</span></li>
</ul>
CSS:
.sub-toggle{
display:block;
padding: 20px;
}
.sub-toggle.active{
background-color: #ffcc00;
color: #fff;
}
Javascript (jQuery):
jQuery(function($){
var i = 1;
// check if browser size is compatible with click event
onResize = function() {
// if browser size is ok, do the click function
if($(window).width() <= 480){
// click function
$('.sub-toggle').click(function(){
alert('click');
if($(this).hasClass('active')){
alert('active');
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
} else{
// if browser size is greater than expected, unbind the click function
$('.sub-toggle').removeClass('active').unbind('click');
}
// just checking how many times the resize function is triggered
console.log('resize: '+ i);
i++;
}
$(document).ready(onResize);
var timer;
$(window).bind('resize', function(){
timer && clearTimeout(timer);
timer = setTimeout(onResize, 500);
});
});
(Edited to remove some unnecessary code)
If you want to see it in action, I've made a Fiddle (try resize the output frame to see it working): http://jsfiddle.net/C7ppv/1/
Maybe I've missing something really stupid, since I don't have a huge knowledge in JavaScript. But what I want to do is just trigger the click event once, even if multiple resizes.
I hope I could explain well my problem. I've searched and didn't found a solution for this issue (or maybe I just didn't know really well what to look for).
Any help would be appreciated!
Your code currently binds a new click events every time the method onResize is called and the window width is less than or equal to 480px.
Simply unbind any existing click events on the .sub-toggle element before binding a new one.
$('.sub-toggle').unbind('click').click(function() {
...
});
DEMO
The resize event is triggered multiple times during resizing, and each time you're binding a new click handler. My suggestion: bind only once, from outside the resize handler, and set a flag while resizing to let the click handler know if it should do something or not.
Then you won't even need to defer the handling of resize with setTimeout as you're doing.
DEMO
jQuery(function($){
var i = 1;
// flag to allow clicking
var clickAllowed = true;
// click function
$('.sub-toggle').click(function(){
if(clickAllowed) {
alert('click');
if($(this).hasClass('active')){
alert('active');
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
}
});
// check if browser size is compatible with click event
onResize = function() {
//if browser size is ok, do the click function
if($(window).width() <= 480){
clickAllowed = true;
}
else{
// if browser size is greater than expected, disallow clicking
clickAllowed = false;
}
// just checking how many times the resize function is triggered
console.log('resize: '+ i);
i++;
}
$(document).ready(onResize);
var timer;
$(window).bind('resize', onResize);
});
Move $('.sub-toggle').click(function(){...} outside the onResize event handler and move if($(window).width() <= 480){...} into the click handler.

How can I prevent the page from scrolling down when using jQuery UI hide("slide")?

here is my code :
$('#pagelinks > a').click(function () {
$('html,body').animate({ scrollTop: 0 }, 200);
setTimeout(function() {$('#my_div').hide("slide",{direction:"right"},500);},250);
return false;
});
My problem is this : When I click on a link, it scrolls up at the top correctly but then automatically scrolls down ( seems to be around where I clicked ) and hide the content of my_div by sliding it and stay there.
I don't want it to scroll down to where I clicked but rather stay at the top. I tried everything I know but nothing works.
Note that if I put just hide() instead of hide("slide",{direction:"right"},500) there is no scroll down. Plus the scroll down occurs on Firefox and Opera but not in Chromium.
Thanks for your help,
Nolhian
I can think of two options:
1) Don't use a-links with anchors if you don't use the anchor part the way it was ment to.
2) stop the default event from occuring by passing on event to the click function and using preventDefault.
example:
.click(function(e){ e.preventDefault(); });

on Click running twice

http://jsfiddle.net/uTV5k/19/
Hello,
I am using the below script on my mobile site. Please see the jsfiddle of simulated script and markup.
The script below is exactly what's on my mobile site, and the js fiddle is a replicate of it.
In the jsfiddle, the click alternations work fine. The first click opens the animation, and the second click closes the animation.
The problem on my mobile site, the first click opens the animation, and the second animation runs immediately after with-out a second click. But in the fiddle it runs OK.
$(window).load(function(){
$(window).bind("orientationchange resize", function(e) {
$('.home-mod').each(function() {
var homeModule = $(this).height(),
homeTitle = $(this).find('.home-title-button').outerHeight(),
homeStart = homeModule - homeTitle,
homeOpen = false;
$(this).find('.mod-info').css("top", homeStart + "px");
$(this).on('click', function () {
if (homeOpen) {
// second click alternation
$(this).find('.mod-info').animate({ top: homeStart + "px" });
homeOpen = false;
} else {
// first click alternation
$(this).find('.mod-info').animate({ top: 0 });
homeOpen = true;
}
});
});
}).trigger("resize");
});
I'm really not sure why this would be happening. Using this in iScroll shouldnt cause any problems should it?
Thanks in advance
firstly : window load happens
you are calling
.trigger("resize");
which activates the bind on click.
later on - if the window load happens again - it retrigger the code which again - re bind the click
The difference between your fiddle code and your live code is the presence of the resize/orientation handler.
All your other code is inside that meaning that it will get run every time your run your resize handler. http://jsfiddle.net/uTV5k/20/ is a variant of your fiddle with that handler back in. It misbehaves badly.
You can fix this by removing the old click handlers before adding the new ones using .off('click').
This fiddle includes this update and seems to behave again: http://jsfiddle.net/uTV5k/21/
The other (and possibly better) way of fixing this issue is to just recalculate the values you need to in the on resize and store them more globally. Then your click functions can be added once and refer to these global values. This is a much bigger code rewrite and I just went for the very simple fix to highlight your problem.

Categories