Why doesn't my jQuery respond to window resize? - javascript

I'm using jQuery to add some make some elements on a page transition (via the jQuery Transit plugin) when hovered upon. Since I'm trying to design responsively, I want these transitions to only happen when the browser is a certain size or larger.
I've written the following code as an attempt to do this:
$(document).ready(function(){
var $window = $(window);
var $logo = $('.logo');
function checkWidth() {
windowsize = $window.width();
}
checkWidth();
$(window).resize(checkWidth);
if (windowsize >= 768) {
$logo.hoverIntent(
function(){
$logo.transition({
perspective: '600px',
rotateY: '-10deg'
});
},
function(){
$logo.transition({
perspective: '600px',
rotateY: '0deg'
});
}
);
}
});
If I load the page in a large browser, it works as expected--the hover effect is active. If I resize the browser, making it smaller (past the breakpoint) and refresh, then it works--the hover effect is disabled. But if I resize the window without refreshing in between, then the effect doesn't respond--it either remains disabled (if resizing from a small to a large screen) or active (if resizing from large to small).
It's a minor quirk, to be sure, but I can't exactly figure out why it's happening. As far as I can tell, when the window resizes, it should be updating the windowsize variable, which should be checked in the if statement. What am I overlooking that makes this not the case?

All checkWidth currently does is assign a value to windowsize. You need to move the code that actually reads windowsize into checkWidth.
$(document).ready(function(){
var $window = $(window);
var $logo = $('.logo');
function checkWidth() {
windowsize = $window.width();
if (windowsize >= 768) {
$logo.hoverIntent(
function(){
$logo.transition({
perspective: '600px',
rotateY: '-10deg'
});
},
function(){
$logo.transition({
perspective: '600px',
rotateY: '0deg'
});
}
);
}
}
// can trigger the resize handler instead of
// explicitly calling checkWidth()
$(window).resize(checkWidth).resize();
});

Related

Jquery function only loads after page refresh

I have roughly around 50 video thumbnails on a set page.
I would like to resize them depending on the resolution.
What I have tried was using #media query in css that did not work as expected then I moved over to this.
$(document).ready(function(event) {
var width = $(window).width();
// Change thumbnail size if browser width changes (should be in real-time)
if (width <= 1300) {
console.log(width);
$('.mdl-cell').removeClass('mdl-cell--3-col').addClass('mdl-cell--4-col');
} else {
$('.mdl-cell').removeClass('mdl-cell--4-col').addClass('mdl-cell--3-col');
}
});
After inserting that script the video thumbnail size changes but as I adjust the browser the jQuery does not load and resize the thumbnail unless the page is refreshed ?
Im not sure as to why the jQuery is not loading the script in real time as the size (browser) changes.
Languages that I am using in this project : PHP, jQuery
you need to catch window resize event with jQuery and also write your code there.
$(window).resize(function() {
var width = $(window).width();
// Change thumbnail size if browser width changes (should be in real-time)
if (width <= 1300) {
console.log(width);
$('.mdl-cell').removeClass('mdl-cell--3-col').addClass('mdl-cell--4-col');
} else {
$('.mdl-cell').removeClass('mdl-cell--4-col').addClass('mdl-cell--3-col');
}
});
To reduce code repetition you can make a function and call it in both $(window).resize() and $(document).ready()
function onResize() {
var width = $(window).width();
if (width <= 1300) {
$('.mdl-cell').removeClass('mdl-cell--3-col').addClass('mdl-cell--4-col');
} else {
$('.mdl-cell').removeClass('mdl-cell--4-col').addClass('mdl-cell--3-col');
}
}
$(document).ready(onResize);
$(window).resize(onResize);
This should work, but it would be much better if it were done with css. Would love you help you with that if you want to post what you tried. If you do it with css, you will not have the jumping on the page that'll occur when the js loads and changes those classes in and out.
You can do smth like this.
Note: this is untested code
function updateSizes(){
var width = $(window).width();
if (width <= 1300) {
$('.mdl-cell').removeClass('mdl-cell--3-col').addClass('mdl-cell--4-col');
} else {
$('.mdl-cell').removeClass('mdl-cell--4-col').addClass('mdl-cell--3-col');
}
}
$(document).ready(function(event) {
updateSizes();
// do other stuff here
});
$( window ).resize(function() {
updateSizes();
// do other stuff here
});

Stop/Restart an animation loop on window resize

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*
}
});

Dynamically resize iframe

Situation:
I'm working on a responsive design that involves the typical HTML/CSS combo. Everything is working nicely except in one case where there is an iframe inside of a div. The iframe should adjust automatically to the size of the parent div. A purely css solution has not presented itself so I'm going with a JQuery approach. It works nicely except in one scenario, when resizing from a smaller width to a larger width screen.
HTML:
<div class="container">
<iframe class="iframe-class" src="http://www.cnn.com/"></iframe>
</div>
CSS:
.container {
width: 100%;
height: 250px;
}
.iframe-class {
width: 100%;
height: 100%;
border: 1px solid red;
overflow: auto;
}
Javascript:
$(function () {
setIFrameSize();
$(window).resize(function () {
setIFrameSize();
});
});
function setIFrameSize() {
var ogWidth = 700;
var ogHeight = 600;
var ogRatio = ogWidth / ogHeight;
var windowWidth = $(window).width();
if (windowWidth < 480) {
var parentDivWidth = $(".iframe-class").parent().width();
var newHeight = (parentDivWidth / ogRatio);
$(".iframe-class").addClass("iframe-class-resize");
$(".iframe-class-resize").css("width", parentDivWidth);
$(".iframe-class-resize").css("height", newHeight);
} else {
// $(".iframe-class-resize").removeAttr("width");
// $(".iframe-class-resize").removeAttr("height");
$(".iframe-class").removeClass("iframe-class-resize");
}
}
http://jsfiddle.net/TBJ83/
Problem:
As the window is resized smaller, it continually checks the window width and once it hits < 480 px, the code adds a class called iframe-class-resize and sets the width and height to that class. As the window is resized larger, it removes the class once the size hits 480 px. The problem is that setting the width and height attributes adds them directly to the element and not the class itself. Therefore, removing the class does not remove the new width and heights. I tried to force removing the attributes using removeAttr() (commented out above) but that didn't work.
Anyone see where the code above went wrong? Or any suggestions on how to accomplish having a responsive iframe more effectively? The main things that are required are that the iframe has to be inside the <div></div> and the div may not necessarily have a width or height defined. Ideally, the parent div should have the width and height explicitly defined but the way this site is currently setup, that won't always be possible.
Additional:
In case the above wasn't clear enough, try the following to reproduce the issue:
Open up a browser on a desktop machine. I'm using Chrome on a Windows machine. Don't maximize the browser.
Open up the jsfiddle above (http://jsfiddle.net/TBJ83/). You'll notice that the iframe content spans the entire width of the Preview panel.
Manually resize the width down until the entire window is < 480px. At this point, the iframe content will be pretty tiny.
Manually resize the width back up until the entire window is >> 480px. The goal is to have that iframe content to regain the entire width of the Preview panel. Instead, the content is retaining the resized width and height since the .css() function applies css changes directly to elements rather than to the classes.
Thanks in advance!
You can do this in about 30 characters. Change:
$(".iframe-class").removeClass("iframe-class-resize")
to:
$(".iframe-class").removeClass("iframe-class-resize").css({ width : '', height : '' })
This will reset the width/height you applied to the element. When you use .css() you add whatever you pass-in to the style attribute of the element. When you pass a blank value, jQuery removes that property from the style attribute of the element.
Here is an updated fiddle: http://jsfiddle.net/TBJ83/3/
EDIT
OK, here's something tweaked for performance (and just some other ways to do things):
$(function () {
//setup these vars only once since they are static
var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once
ogWidth = 700,
ogHeight = 600,
ogRatio = ogWidth / ogHeight,
windowWidth = 0,//store windowWidth here, this is just a different way to store this data
resizeTimer = null;
function setIFrameSize() {
if (windowWidth < 480) {
var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page
newHeight = (parentDivWidth / ogRatio);
$myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth });
} else {
$myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' });
}
}
$(window).resize(function () {
//only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function
//this way you don't blow up someone's browser with your resize function running hundreds of times a second
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
//make sure to update windowWidth before calling resize function
windowWidth = $(window).width();
setIFrameSize();
}, 75);
}).trigger("click");//run this once initially, just a different way to initialize
});
This can be done using pure CSS as below:
iframe {
height: 300px;
width: 300px;
resize: both;
overflow: auto;
}
Set the height and width to the minimum size you want, it only seems to grow, not shrink.
This is how I would do it, code is much shorter: http://jsfiddle.net/TBJ83/2/
<div class="container">
<iframe id="myframe" src="http://www.cnn.com/"></iframe>
</div>
<script>
$(function () {
setIFrameSize();
$(window).resize(function () {
setIFrameSize();
});
});
function setIFrameSize() {
var parentDivWidth = $("#myframe").parent().width();
var parentDivHeight = $("#myframe").parent().height();
$("#myframe")[0].setAttribute("width", parentDivWidth);
$("#myframe")[0].setAttribute("height", parentDivHeight);
}
</script>
I did it that way for read-ability, but you could make it even shorter and faster...
function setIFrameSize() {
f = $("#myframe");
f[0].setAttribute("width", f.parent().width());
f[0].setAttribute("height", f.parent().height());
}
One selector, so you only look through the DOM once instead of multiple times.
For those using Prestashop, this is how I used the code.
In the cms.tpl file I added the below code:
{if $cms->id==2}
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script>
<script type="text/javascript" src='../themes/myheme/js/formj.js'></script>
<div style="width: 100%; height: 800px;">
<iframe style=" width: 100%; height: 100%; border: overflow: auto;" src="https://cnn.com"></iframe>
</div>
{/if}
Then created a new js file: formj.js and added the below code:
$(function () {
//setup these vars only once since they are static
var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once
ogWidth = 970,
ogHeight = 800,
ogRatio = ogWidth / ogHeight,
windowWidth = 0,//store windowWidth here, this is just a different way to store this data
resizeTimer = null;
function setIFrameSize() {
if (windowWidth < 480) {
var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page
newHeight = (parentDivWidth / ogRatio);
$myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth });
} else {
$myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' });
}
}
$(window).resize(function () {
//only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function
//this way you don't blow up someone's browser with your resize function running hundreds of times a second
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
//make sure to update windowWidth before calling resize function
windowWidth = $(window).width();
setIFrameSize();
}, 75);
}).trigger("click");//run this once initially, just a different way to initialize
});

jQuery hover animations based on viewport size

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.

Can I execute javascript based on window size?

I have a responsive site where I'm using a javascript to create a sticky sidebar.
I'm also using media queries to change from a multi-column layout to a single-column layout when the browser size is less than 768px.
I need to figure out how to disable the sticky menu script in the single-column layout. Essentially, I need something like a media query for the script statement.
This is the code I'm using to enable the script:
<script>
jQuery('#info').containedStickyScroll({
duration: 0,
unstick: false
});
</script>
Is there something I can add to it to only have it trigger if the window is 768px wide or wider?
EDIT: I'm looking for a solution that will work if the user resizes the window on the fly.
Try this.
$(function(){
$(window).resize(function(){
if($(this).width() >= 768){
jQuery('#info').containedStickyScroll({
duration: 0,
unstick: false
});
}
})
.resize();//trigger resize on page load
});
Try this code:
var height = $(window).height(); //I'm assuming you mean height, you can try .width() if yo u need it
if (height < 768) {
jQuery('#info').containedStickyScroll({
duration: 0,
unstick: false
});
}
Hope that helps.
Check this out:
var targetWidth = 768;
if ( $(window).width() >= targetWidth) {
//Add your javascript for screens wider than or equal to 768 here
jQuery('#info').containedStickyScroll({
duration: 0,
unstick: false
});
}
else {
//Add your javascript for screens smaller than 768 here
console.log(`am less than ${targetWidth}`)
}

Categories