in the process of learning more jQuery and have an issue with some code.
I am attempting to have an animation effect (fadeIn/fadeOut) when the user hovers over a specific element.
However, when the viewport is resized, ie below 480px for mobile display, I need the hover effects to be ignored and just display the call to action. In my code below I am trying to detect the viewport and then apply the appropriate script through an if-then-else statement.
I suspect that I'm not nesting something properly or have a misplaced semi-colon. I've been staring at this a while and am stuck.
I did look at these other posts as reference.
http://j.mp/1hejP0B
http://j.mp/1hejRFK
Let me know if you have any questions or can provide additional details.
// Script to display div call-to-action over logos
var detectViewPort = function(){
var viewPortWidth = $(window).width();
// if its bigger than 480px then do the hover effect
if (viewPortWidth > 480){
// On mouse over logo
$('.unionlogo').hover(function() {
// Display the call to action
$(this).find('a.calltoaction').stop(false,true).fadeIn(400);
$(this).find('p.union-name').stop(false,true).fadeOut(400);
},
function() {
// Hide the call to action
$(this).find('a.calltoaction').stop(false,true).fadeOut(400);
$(this).find('p.union-name').stop(false,true).fadeIn(400);
});
// if its smaller than 480px then just show the call-to-action
}else{
$('a.calltoaction').show();
};
$(function(){
detectViewPort();
});
$(window).resize(function () {
detectViewPort();
});
Did you look in your console to see what the error message was? As you said, you left off a bracket. You should be formatting your code a little better, and it would have been obvious.
var detectViewPort = function(){
var viewPortWidth = $(window).width();
// if its bigger than 480px then do the hover effect
if (viewPortWidth > 480){
$('a.calltoaction').hide();
// On mouse over logo
$('.unionlogo').off('mouseenter mouseleave');
$('.unionlogo').hover(function() {
// Display the call to action
$(this).find('a.calltoaction').stop(false, true).fadeIn(400);
$(this).find('p.union-name').stop(false, true).fadeOut(400);
}, function() {
// Hide the call to action
$(this).find('a.calltoaction').stop(false, true).fadeOut(400);
$(this).find('p.union-name').stop(false, true).fadeIn(400);
});
// if its smaller than 480px then just show the call-to-action
} else {
$('.unionlogo a.calltoaction').stop(false,true).fadeOut(400);
$('.unionlogo p.union-name').stop(false,true).fadeIn(400);
$('a.calltoaction').show();
// un bind the hover incase of browser resize
$('.unionlogo').off('mouseenter mouseleave');
};
}
$(function(){
$(document).ready(function(){
detectViewPort();
});
});
$(window).resize(function () {
detectViewPort();
});
Maybe try adding a media query to the CSS to hide the original button and add a call to action button when the view port is 480px or less.
Related
I'm following a guide that allows Google Map screen to disable scrolling depending on the screen size. The only part i'm struggling is to write a code that dynamically changes the True/False value when i resize the screen manually.
This is the website that I followed the instruction but I can't seem to write the correct syntax code to produce the dynamic true false value depending on the screen size https://coderwall.com/p/pgm8xa/disable-google-maps-scrolling-on-mobile-layout
Part of the code that i need to use:
$(window).resize()
And then:
setOptions()
So I'm struggling to combine them together.
I have tried something like this:
var dragging = $(window).width(function resize() {
if (dragging > 560) {
return true;
} else {
return false;
}
});
The article you linked to is lacking important information as it fails to mention that $ is (presumably) jQuery. But you don't need jQuery at all.
What you can use instead is the MediaQueryList. It is similar to media queries in CSS, but it is a JavaScript API.
The following is an untested example of how you might use it with a MediaQueryList event listener. It sets the initial value and listens to changes to your media query with a handler that uses setOptions from the Google Maps API.
var mql = window.matchMedia('(min-width: 560px)');
var isDraggable = mql.matches;
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
draggable: isDraggable
});
}
function mqChange(e) {
map.setOptions({draggable: !!e.matches});
}
mql.addListener(mqChange);
You could add an event listener to the resize event and set a value of your variable whenever the size of the window is changed:
var dragging = false;
window.addEventListener('resize', function(event) {
dragging = window.innerWidth > 560;
});
Since you mentioned that you want to disable scrolling when the windows size extends a certain value, it might be easier to just do this. If you try it you can see in the console that the value changes whenever you resize your window):
window.addEventListener('resize', function(event) {
console.log(window.innerWidth);
if (window.innerWidth > 560) {
// disable scrolling or do whatever you want to do
}
});
BTW, in your code you do this:
if (dragging > 560) {
return true;
} else {
return false;
}
You can simplify this to:
return dragging > 560
Which is exactly the same.
You can use this function to get the width and height on a resize of the screen.
$(window).resize(function() {
$windowWidth = $(window).width();
$windowHeight = $(window).height();
// run other functions or code
});
But, if you want to only show/hide a html element based on the screen size, you can also use plain html/css.
<div id="maps"></div>
Css:
#media only screen and (max-width: 560px) {
#maps {
display: none;
}
}
you can use the matchMedia function to run a callback whenever the media query status is changing
var mql = window.matchMedia('(min-width: 700px)');
function mediaHandler(e) {
if (e.matches) {
/* the viewport is more than 700 pixels wide */
} else {
/* the viewport is 700 pixels wide or less */
}
}
mql.addListener(mediaHandler);
jQuery(window).scroll( function(){
/* Check the location of element */
jQuery('.logoscrollbg').each( function(i){
var logo = jQuery(this).outerHeight();
var position = jQuery(window).scrollTop();
/* fade out */
if( position > logo ){
jQuery(this).animate({'opacity':'1'},100);
}else{ jQuery(this).animate({'opacity':'0'},100);}
});
});
Above is my script for a class (the header) with should blend in when the page is being scrolled down and blend out when you are on the top of the page, with other words the start.
I don't understand javascript at all, but I do a little php and I was wondering if someone could help me write there a elseif tag and later make the else tag so that is the page is loaded the class(.logoscrollbg) isn't visible and when u start scrolling it gets visible and when you get to the top it gets invisivle again :)
The script works like this right now: when I enter the site it shows the bar(bad), later when scrolling it stays or well is there(good), then when getting to top again it fades out(good).
The code inside your scroll event needs to be run when the page is loaded as well as when it scrolls.
jQuery(function() {
// object to hold our method
var scrollCheck = {};
// define and call our method at once
(scrollCheck.check = function() {
// only need to get scrollTop once
var logo, position = jQuery(window).scrollTop();
/* Check the location of element */
jQuery('.logoscrollbg').each(function() {
logo = jQuery(this).outerHeight();
/* fade out or in */
// cleaned this up a bit
jQuery(this).animate({'opacity': position > logo ? 1 : 0}, 100);
});
})();
jQuery(window).scroll(function(){
// call our method
scrollCheck.check();
});
});
It looks to me like this will only fire when you scroll. Try updating your js to this:
jQuery(window).on('scroll, load', function() {
/* Check the location of element */
jQuery('.logoscrollbg').each( function(i){
var logo = jQuery(this).outerHeight();
var position = jQuery(window).scrollTop();
/* fade out */
if( position > logo ){
jQuery(this).animate({'opacity':'1'},100);
}else{ jQuery(this).animate({'opacity':'0'},100);}
});
});
*note: You may want to fire the callback on document load instead of window.
The things here are like this (long story but I have a point)
I have a menu with buttons that look like this:
*******
***B***
*******
An when you hover it expands
*************
***Button****
*************
Now, when the screen is for mobile, no more hexagons, they stack up like normal buttons, with the complete text showing instead of having to hover to read.
my markup is as follows:
S<span class="comptxt">ervicios</span>
C<span class="comptxt">ontacto</span>
F<span class="comptxt">aq</span>
B<span class="comptxt">log</span>
And I'm using jQuery to show and hide the span tags on hover and css to handle the width of the anchor tag.
$('a.btn').hover(function() {
$(this).children('span').fadeIn(500);
$('img').css('opacity', 0.5);
}, function() {
$(this).children('span').fadeOut(200);
$('img').css('opacity', 1);
});
so fade in on hover fade out when not hover.
BUT I put this javascript on an IF conditional, if the screen resizes to mobile (i'm using 500px and below as mobile) this code shouldn't run, here is the if conditional:
$(window).resize(function() {
if ($(window).width() < '501') {
$('a.btn').hover(function() {
$(this).children('span');
$('img').css('opacity', 0.5);
}, function() {
$(this).children('span');
$('img').css('opacity', 1);
});
};
if ($(window).width() > '500') {
$('a.btn').hover(function() {
console.log($(window).width());
$(this).children('span').fadeIn(500);
$('img').css('opacity', 0.5);
}, function() {
//this part of the code runs even if the window is below 500
$(this).children('span').fadeOut(200);
$('img').css('opacity', 1);
});
};
});
It's freaking me out that the conditional doesn't met and the code still runs.
Tha problem with this is that when the buttons are normal and you hover over them after the resize, the text fades out
Other thing: when you load the page and the screen is below 500 it works as it should, no fading out. The problem arises when you resize above 500 and resize back down below 500, then the fadeout happens again.
On the resize event you never remove the previous event handler from when the window was at a larger size. You can achieve this using off():
$(window).resize(function() {
if ($(window).width() < '501') {
$('a.btn').off('hover').hover(function() {
// rest of your code...
});
};
if ($(window).width() > '500') {
$('a.btn').off('hover').hover(function() {
// rest of your code...
});
};
});
A better solution may be to instead check the size of the window within the hover handler itself as detaching/attaching events for every single pixel that the window is resized is going to end up being very slow. Try this:
$(function() {
$('a.btn').hover(function() {
var opacity = $(window).width() < 501 ? 0.5 : 1;
$('img').css('opacity', opacity);
}, function() {
var opacity = $(window).width() < 501 ? 1 : 0.5;
$('img').css('opacity', opacity);
});
});
.hover(), like .click() and other functions, are additive with jQuery.
Every time the window is resised, you bind an additional function on hover.
I mean, if the window is resized by 200 pixels, you bind the function 200 times, and it will actually be executed 200 times on hover.
It's also true when you expand the window : hover functions will continue to be bond. So, on hover, 200 "small screen" functions will be executed, and 200 "large screen" functions will be executed. This is a terrible design.
At least, you have to unbind hover() before applying a new one :
$('a.btn').unbind('mouseover mouseout').hover(
Your code does not run, because you put it inside $(window).resize. It will only run when the screen is resized, but never on hover.
I have an animation where three images rotate up and down. JSfiddle: http://jsfiddle.net/rLgkyzgc/1/
$(window).load(function() {
// Load images in BG that have been hidden by CSS
$('.banners').show();
// Create an empty array
var banners = [];
// Fill array with banner ids
$('.banners').each(function () {
var banner = $(this).attr('id');
banners.push(banner);
});
function switchBanners(){
var $firstBanner = $('#' + banners[0]);
var $secondBanner = $('#' + banners[1]);
var firstBannerHeight = $firstBanner.height();
var secondBannerHeight = $secondBanner.height();
$firstBanner.animate({ bottom: -firstBannerHeight }, 1200);
$secondBanner.animate({ bottom: 0 }, 1200, function(){
b = banners.shift(); banners.push(b);
setTimeout(function(){
switchBanners();
}, 4000);
});
};
// Delay initial banner switch
setTimeout(function(){
switchBanners();
}, 4000);
});
This is great for the desktop view, but on mobile, I want to stop the animation and just show one static image.
So my questions. How can I :
Only start the animation on page load if the window width is > 940px
Stop (reset) the animation if the page is resized to be < 940px wide
THEN restart the animation if the page resized to be > 940px wide
You should use window.matchMedia (see the documentation) to detect the viewport size on document.ready and when the window is resized, so something like this:
function resetAnimation() {
$firstBanner.stop(true, true);
$secondBanner.stop(true, true);
if(window.matchMedia("(min-width: 940px)").matches) {
//Start the animations here
}
}
$(document).ready(function() {
resetAnimation();
}
$(window).resize(function() {
resetAnimation();
}
Note that you don't really need to stopthe animations on document.ready, but this way you have a single function to reset the animations and then restart them only if necessary, which is something you typically want to do every time you resize the browser window, regardless of the viewport size.
I'll reference these in order:
1. Only start the animation on page load if the window width is > 940px
In your window load function, grab your browser width with $(window).width(). Then check that against your 940 (leave off the "px"), and perform necessary actions.
So:
if ($(window).width() > 940){ *actions* }
2. Stop (reset) the animation if the page is resized to be < 940px wide
To do this, you'll need to use the window resize function ($(window).resize()) and check your 940 against the browser width.
So:
$(window).resize(function(){
if ($(window).width() <= 940){
*stop (reset) animation*
}
});
3. THEN restart the animation if the page resized to be > 940px wide
This logic is essentially the same as #2, just reversed:
$(window).resize(function(){
if ($(window).width() > 940){
*restart animation*
}
});
I am making a login page in which I use a little javascript and jquery to vertically align the login box.
I also have an event on resize() to put the box in the middle again.
But, with resize(), everytime the user resize the window, the function is fired and this is a kind of ugly :))
So, I would like to know if there is a way to fire the function only on vertical resize.
Thank you
It will fire every time, but you can track the width to check for only vertical resizing:
// track width, set to window width
var width = $(window).width();
// fire on window resize
$(window).resize(function() {
// do nothing if the width is the same
if ($(window).width()==width) return;
// update new width value
width = $(window).width();
// ... your code
});
Instead of comparing heights for each situation where you want to detect vertical resize, you can create reusable events for horizontal and vertical resizing like this:
// Horizontal and vertical window resize events.
(function () {
var win = jQuery(window),
prev_width = win.width(),
prev_height = win.height();
win.on('resize', function () {
var width = win.width(),
height = win.height();
if (width !== prev_width) {
win.trigger('hresize');
}
if (height !== prev_height) {
win.trigger('vresize');
}
prev_width = width;
prev_height = height;
});
})();
That way you can just drop that code in place once, and then use the events like this:
$(window).on('hresize', function () {
// handle horizontal resizing
});
$(window).on('vresize', function () {
// handle vertical resizing
});
Got better solution:
$('#element').resizable({
stop: function( event, ui ) {
$('#element').height(ui.originalSize.height);
}
});
As a complement to Doublesharp's useful answer:
In my case, window.outerWidth worked better, and was stable to vertical resizes.
Indeed, I had some troubles with $(window).width() : it (strangely!) happened to be modified also when I only resized vertically.