Window.resize doesn't work unless page is reloaded - javascript

I have this responsive layout. What I want to achieve is that at "desktop" size, once a menu link is clicked it will navigate to that part of the page. I want the same thing for "mobile" size. Also, once the menu links are clicked, the menu will slideUp.
I have both of these things working, however it only works when the page is reloaded. To summarize, here are the problems:
At desktop size: navigation is fine, but when resized to mobile the menu doesn't show.
At mobile size: navigation works fine, when resized to desktop it also works fine, but the menu keeps on toggling.
I created a jsFiddle for it. Here is my code:
HTML
<div id="head" class="clearfix">
Pull Menu
<div class="menu-wrap clearfix">
<div class="nav">
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
</div>
</div>
</div>
<div id="test1" class="section">Test1</div>
<div id="test2" class="section">Test2</div>
<div id="test3" class="section">Test3</div>
JavaScript
var respMenu = function(event) {
var menu = $('.menu-wrap');
if ($(window).width() < 501) {
$("#pull").on('click', function() {
menu.slideToggle('slow');
});
$(".nav ul li a").click(function() {
menu.slideUp('slow');
});
}
else{
}
return false;
event.preventDefault();
};
var onClick = function() {
$('a').bind('click',function(event){
var $anchor = $(this);
if ($(window).width() > 500) {
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top - 90 }, 1000,'easeInOutExpo');
}
else{
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top - 50 }, 1000,'easeInOutExpo');
}
event.preventDefault();
});
};
$(window).load(function(){
respMenu();
onClick();
});
$(window).resize(function(){
respMenu();
onClick();
});

The issue is that you bind a new handler to the click event each time your window is re-sized and you never unbind them. So the handlers number keep increasing, which means that multiple events will be fired after a click once you've re-sized the window.
So what you can do is to unbind the handlers using the unbind or off methods.
Take a look here: http://jsfiddle.net/yohanrobert/p987prdd/

Related

jQuery scrollTop and focus on element

I have the following scrollTop function:
<a onclick="jQuery('html,body').animate({scrollTop:0},'slow');return false;" class="well well-sm" href="#">
<i class="uxf-icon uxf-up-open-large"></i><span class="sr-only">${message:backToTop}</span></a>
However, when you use your keyboard to navigate the focus does not go to the top. It remains in the footer. Is there a way to bring the focus to the following div:
<div id="top" tabindex="-1"></div>
The visual focus is different from the keyboard focus, you can use the focus() function to define the keyboard focus
<a onclick="jQuery("#top").focus();return false;" class="well well-sm" href="#">...</a>
This can be used conjointly with your animate function.
Animated scrolling to the top of the element, then setting a focus:
<script>
function scroll() {
$('html, body').animate({
scrollTop: $('#top').offset().top
}, 'slow', function() {
$('#top').focus();
});
}
</script>
<a onclick="scroll(); return false;" class="well well-sm" href="#">...</a>
The problem is that you have assignd a click to it, while enter is a keypress, you have to set it both, here's one way to do it with jQuery delegation:
function animateToTop() {
$('html,body').animate({
scrollTop: $('#top').offset().top
}, 'slow');
}
$('#aSendToTop').on('click keypress',
function (e) {
// mouse 1 has keyCode 1, while enter is keycode 13
if( [1, 13].indexOf(e.which) > -1 ) animateToTop();
}
);
JSFiddle

Scrolling to a specific div using window.onload without adding to the web address

I am creating a page with 5 divs. I am using the following JavaScript code to smoothly move between them horizontaly :
$(function () {
$('ul.nav a').bind('click', function (event) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, 1500,'easeInOutExpo');
event.preventDefault();
});
});
The Divs are something like this:
<div class="section white" id="section5">
<h2>Technologies</h2>
<p>
text
</p>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
I want to start with div # 3 on page load. The only solution that worked is the onload function:
window.onload = window.location.hash = 'section3';
but unfortunately when I load the page the url address is
http://localhost:51551/trial1/MainPage.aspx#section3
even when I click on another page anchors (div) and go there the URL is stuck to MainPage.aspx#section3.
I tried the solutions here: jQuery: how to scroll to certain anchor/div on page load?
But I think because I am already using Javascript to navigate the divs, its not working. I want to Either:
Remove the address #section3 part and keep using the onload
function
Even better navigate to section3 at start and have
the url change when I change the section
I am using Visual Studio 2010 Express, with ASP.NET, JS and C#. on Windows 8.1
First the following important distinction:
jQuery's #section1 selector looks for an HTML element with ID "section1", i.e. <div id="section1"></div>
The a href's #section1 URL hash looks for an anchor with name "section1", i.e. <a name="section1"></a>
This is a major difference that you need to check and understand. So you would normally need:
<a name="section1"></a>
<div id="section1">... your content here ...</div>
But since you are scrolling horizontally, I am going to do this without the <a name=...></a> part and deal with the hash in the window load handler, as I will explain further down.
Next is, I would avoid naming a JavaScript variable "event" as that looks an awful lot like a keyword, so try renaming it to ev.
If you want the click handler (the function you bind to the click event) to not follow the link clicked on, that function should return false:
$('ul.nav a').click(function (ev) {
var anchor = $(this);
$('.viewport').stop().animate({
scrollLeft: $($(anchor).attr('href')).offset().left
}, 1500,'easeInOutExpo');
// Add the section ID to the URL
window.location.hash = $(anchor).attr('href').substring(1);
ev.preventDefault();
return false;
});
Then, I'd suggest you to move the <ul class="nav">...</ul> outside of the section divs, so you don't have to repeat it inside your divs. Because you seem to be scrolling left/right, I assume you are floating your section divs next to each other in a wide container:
<div class="viewport">
<div class="container clearfix">
<div class="section" id="section1">
<h2>Technologies</h2>
<p>Text</p>
</div>
<div class="section" id="section2">
... content ...
</div>
<div class="section" id="section3">
... content ...
</div>
</div>
</div>
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Using the following CSS (as an example for 3 600px divs floated next to each other inside a 1800px container, wrapped by a 600px viewport):
.viewport {
width: 600px;
overflow: hidden;
overflow-x: scroll;
}
.container {
width: 1800px;
}
.section {
float: left;
width: 600px;
}
For the clearfix class, refer to Bootstrap's clearfix.
Because you are scrolling horizontally, I think the <a name=...></a> things won't work, so I'd do an onload check for the hash, and scroll there when accessing the page with a preset hash. This has been done in the window load handler in the next snippet, together with starting in section 3 when there is no hash specified:
As for starting in section 3 on load, have this in your $(window).load() handler, for example:
$(window).load(function() {
var startSection = window.location.hash;
if (startSection == "") startSection = '#section3';
$('.viewport').scrollLeft($(startSection).offset().left);
window.location.hash = startSection;
});
Disclaimer: untested code! :) But please try these, and it should get you pretty close to what you are trying to achieve.
Hope this helps!
Why don't you scroll to that div on window load? And change bind with on, as of jQuery 1.7 .on() is the preferred method for attaching event handlers to a document
So your code should be something like this
$(document).ready( function(){
$('ul.nav a ').on('click ', function (event) {
var $anchor = $(this);
$('html, body ').stop().animate({
scrollLeft: $($anchor.attr('href')).offset().left
}, 1500, 'easeInOutExpo ');
event.preventDefault();
});
});
$(window).on('load', function () {
$('html, body').stop().animate({
scrollLeft: $('#section3').offset().left
}, 1500, 'easeInOutExpo ');
});

scroll to the sibling element on click

Please take a look at this FIDDLE that shows and hides the text in a container on click . What I'm trying to do is that when I click open the first hidden text and then scroll down to click open another one, I want it to scroll back to the sibling image of that opened text to keep it in view. How can I find the sibling element and scroll to it on click?
This one is not valid.
$('.slider2').click(function(e) {
var imageposition = $(this).closest('.imageclass');
$(document.body).animate({scrollTop: imageposition.offset().top}, 'fast');
});
HTML:
<div class="container" style="border:2px solid #222;">
<img class="imageclass" style="width:100px;height:100px" src ="image.jpg">
<div class="slider2">Hi</div>
<div class="internal" style="display: block;">Text<p></p></div>
</div>
<div class="container" style="border:2px solid #222;">
<img class="imageclass" style="width:100px;height:100px" src ="image.jpg">
<div class="slider2">Hi</div>
<div class="internal" style="display: block;">Text<p></p></div>
</div>
..............
JS:
$('.slider2').click(function(e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
$('.internal').slideUp('normal');
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
}
var imageposition = $(this).closest('.imageclass');
$(document.body).animate({scrollTop: imageposition.offset().top}, 'fast');
});
$('.internal').hide();
You've at least a couple of problems here
$(this).closest('.imageclass') doesn't select the image that is previous sibling of <a>
even if you get your desired image, the moment your scrolling code runs, the image has not placed itself to its final position.
using $(document.body) to scroll the window (I'm doubtful about it myself)
Below code selects the right image element, gets the scrolltop at right moment, and scrolls the html, body using working syntax.
$(function () {
$('.slider2').click(function (e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
$('.internal').slideUp('normal');
var imageposition = $('.imageclass', $(this).closest('.container'));
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal', function () {
$('html, body').animate({scrollTop: $(imageposition).offset().top})
});
}
});
$('.internal').hide();
});
There's a bit of a problem with how your scrolling function works because the position of the active .container alters in relation to other containers(when active and inactive state).
Also, you should not be looking for the closest position but for its parent element.
Please take a look at my code: CSS
.slider2 {
margin:40px;
}
.internal p {
padding:5px;
}
.internal h3 {
text-align:center;
}
.container {
position: relative;
}
You might need to look for a way, to detect the height of an inactive container since I made mine as a static value.
JS:
$('.slider2').click(function (e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
var containerHeight = 205;
var containerIndex = $(this).offsetParent().index();
$('.internal').slideUp('normal');
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
}
var scrollPosition = containerHeight * containerIndex;
$('body').animate({
scrollTop: scrollPosition
}, 'fast');
});
$('.internal').hide();

Jquery menu doesnt open on touch screen devices

I have a drop down menu where the user selects a location and it scrolls to the div to reveal the address (10 different locations).
This works well in a desktop browser. However on the ipad, iphone and nexus it doesnt work because of touch screen.
This is my code:-
<html>
<div class="location">
<ul>
<li>Select an Office
<ul class="officeselect">
<li><a data-emailaddress="" data-address='<span class="address">99 Walnut Tree Close</span>
<span class="address">Guildford</span>
<span class="address">Surrey</span>
<span class="address">GU1 4UQ</span><br>
<span class="address">T: +44 1483 881500</span>
<span class="address">info#petroplan.com</span>' href="">UK Head</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="span4 alpha">
<div class="addresstitle">
<h3>Address</h3>
</div>
<div class="address">
</div>
</div>
</html>
<script>
// Scroll down to map and address function
$(".location ul li ul a").click(updateAddressDisplay);
function updateAddressDisplay(src) {
$('.office-sel-cont .chooser').text($(this).text());
var target = $(".address");
var source;
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
if (src === null)
source = $(".black-sectors li a.adr-src:eq(0)");
else
source = $(this);
target.fadeOut();
target.html(source.data("address") + source.data("emailaddress"));
target.fadeIn();
var chooser = $(this).parent().parent().parent().find('.chooser');
if (chooser.hasClass('open')) {
chooser.removeClass('open');
chooser.next($('.black-sectors')).animate({
'top': '60px',
'opacity': 0
}, 600, 'easeOutQuint', function() {
chooser.next($('.black-sectors')).toggle();
});
return false;
} else {
}
return false;
}
</script>
And I used this below from this website, but it's still dodgy.
<script>
$('.location ul li ul a').on('click touchend', function(e) {
e.preventDefault();
var el = $(this);
var link = el.attr('href');
window.location = link;
});
</script>
Thanks for your help.
this is the fiddle:-http://jsfiddle.net/ScVs9/
For your drop down list to work on a touch screen device you need to trigger the drop-down using a javascript click event rather than the css hover. Simple way would be create a class, called something like .active and then use a function like this:
$('.location a').on('click', function(){
$('.officeselect').toggleClass('active')
});
The active class would simply have visibility set to visible:
ul.officeselect.active {visibility:visible;}
The user should then be able to select the correct link and display the address as per usual.
I hope this helps

Jquery and Foundation 4 Accordion Deep Linking

I'm using Foundation 4 accordion with deep linking set to true:
<div class="section-container accordion" data-section="accordion" data-options="deep_linking: true">
<section class="section">
<h3 class="title"> Program Highlights <span class="arrow_down"></span></h3>
<div class="content" data-slug="panel1">...
Despite Foundation docs saying this should work, this by itself does nothing... so I added:
$(document).foundation('section', {
callback: function (){
var containerPos = $('.active').offset().top;
$('html, body').animate({ scrollTop: containerPos }, 200);
}
});
This works, but I wanted the accordion panels to close when clicked again, instead of having to click another panel. So I then add some code to toggle open/close each accordion panel and arrow up/down on click:
$(document).on('click','.accordion h3', function () {
$(this).find('span').toggleClass("arrow_down arrow_up");
$(this).next('div').toggle();
var containerPos = $(this).offset().top;
$('html, body').animate({ scrollTop: containerPos }, 200);
});
Then only only the foundation callback works, not the toggling. So these both work individually, but when I have both in the script only the foundation callback works. How can I get both of these to work?
You can use data-options="one_up: true;" to collapse the content of you accordion. For example:
<div data-options="one_up: true;" data-section="accordion" class="section-container accordion"></div>

Categories

Resources