Dynamically add class on browser resize (viewport width) - javascript

I have an element called jobfilter, which I want to add a class to depending on the viewport width, ie. when I resize my browser to <1000px, I want to add the class .hidden to .jobfilter.
Now, I managed to get it half-working with the help of this link: $(window).width() not the same as media query.
Using this:
function checkPosition() {
if (window.matchMedia('(max-width: 767px)').matches) {
//...
} else {
//...
}
}
Here's my JSFiddle: http://jsfiddle.net/ck55Lf01/10/.
If you resize the browser and refresh the page, the jobfilter hides, but I'd like that to happen dynamically, not on the refresh of the page, thank you for your help!

This is a fucnction I use to dynamically check the window width on resize, I wrapped it in a document ready function that passes the $ as a parameter to prevent any conflicts that might occur with other javascript libraries that use the $. An example would be if you were to use your function inside of a wordpress theme or plugin.
Jsfiddle example: http://jsfiddle.net/larryjoelane/ck55Lf01/24/
Javascript:
/*
document ready function used to prevent conflict with other javascript libraries
that use the $ parameter
*/
jQuery(document).ready(function($){
//get the window width
var winWidth = $(window).width();
//set the maxWidth
var maxWidth = 1000;
//if the window width is less than the maxWidth pixels on document loading
if(winWidth < maxWidth){//begin if then
//add the class hidden to .jobFilter
$(".jobfilter").addClass("hidden");
}//end if then
$(window).resize(function(){//begin resize event
//get the window width
var winWidth = $(window).width();
//set the maxWidth
var maxWidth = 1000;
//if the window width is less than maxWidth pixels
if(winWidth < maxWidth){//begin if then
//add the class hidden to .jobFilter
$(".jobfilter").addClass("hidden");
}
else{
//remove the class hidden
$(".jobfilter").removeClass("hidden");
}//end if then else
});//end window resize event
});//end document ready function

Update August 2021
It's still a little-known fact that matchMedia has an event listener. It triggers a "change" event whenever it changes. You can use that to toggle a class depending on whether or not it matches, and listen for that match changing without having to bind anything to the (potentially heavy) window resize event.
function doSomething(matches) {
if (matches) {
// media query matches
} else {
// media query does not match
}
}
const query = window.matchMedia("(max-width: 767px)");
query.addEventListener("change", ({ matches }) => doSomething(matches));
doSomething(query.matches);
This is also mentioned on MDN.
Original Answer
Little known fact: matchMedia has an event listener:
function handleMedia(mql) {
if (mql.matches) {
// media query matches
} else {
// media query does not match
}
}
var mql = window.matchMedia('(max-width: 767px)').addListener(handleMedia);
handleMedia(mql);
The event listener will execute every time the browser matches or unmatches the media query. In your case, I'd recommend firing the handler manually as well (as shown in the example) to be sure to get the correct class set on load.
This example is taken from MDN (although it's pretty well hidden).

you have to listen on the resize event.
$( window ).resize(function() {
checkPosition();
});

Use the resize event to check if the window is resized or not. Use this code
$( window ).resize(function() {
function checkPosition() {
if (window.matchMedia('(max-width: 767px)').matches) {
//...
} else {
//...
}
}
}
Hope this helps you

$(document).ready(function(){
DOaction(); // run function after document ready
$(window).on('resize',DOaction); // on resize window run function
});
// function to add and remove hidden class
function DOaction(){
if($(window).width() <= 1000){
$(".jobfilter").addClass('hidden');
}else{
$(".jobfilter").removeClass('hidden');
}
}
Jsfiddle

Related

How to use jquery resize run funtion one time?

I want to use run 2 functions jquery when resize window. But I just want to do they one time. code can be like:
jQuery(document).ready(function () {
var screenwidth=jQuery(window).width();
if(screenwidth>991){
dofunction1();
}
else{
dofunction2();
}
});
I want when screenwidth>991 do dofunction1() 1 time, and when screenwidth<=991 do dofunction2() 1 time. Hope your help!!
You can use .one() to bind resize event
Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
$(window).one('resize', function () {
var screenwidth = jQuery(window).width();
if (screenwidth > 991) {
dofunction1();
} else {
dofunction2();
}
});

Execute javascript only above certain width with resize

I'm currently developing a website which has a sticky menu function. I've got the normal javascript to work good, which adds some classes once the client scrolls past 150px.
I now face the problem that I don't want the classes to be added once people view the website below 725px, so I added a rule that it only executes the script above 725px but the problem is this:
If I resize the window back to full the function won't work anymore, so I created another rule with the javascript resize function but I can't get it to work..
Here is my script:
$(document).ready(function(){
var mainbottom = 150;
if($(window).innerWidth() > 725) {
$(window).on('scroll',function(){
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
});
}
});
$(window).resize(function() {
var mainbottom = 150;
if($(window).innerWidth() > 725) {
$(window).on('scroll',function(){
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
});
}
});
I'll hope somebody can help me with this problem.
First off, you should keep your code DRY. So preferably never copy paste any code around, bacause you will have to edit all the copies when you have to alter the behaviour or fix bugs.
You have not but your second $(window).resize() handler in the onready handler, so maybe that is why it is not triggered.
This should work:
$(document).ready(function(){
var mainbottom = 150;
function onScroll () {
stop = Math.round($(window).scrollTop());
if (stop > mainbottom) {
$('.header').addClass('sticky-nav');
$('.logo').addClass('sticky-logo');
$('.navigation').addClass('sticky-menu');
} else {
$('.header').removeClass('sticky-nav');
$('.logo').removeClass('sticky-logo');
$('.navigation').removeClass('sticky-menu');
}
}
var widthExceeded = false;
$(window).resize(function() {
$(window).innerWidth() > 725) {
if (!widthExceeded) {
$(window).on('scroll', onScroll);
}
widthExceeded = true;
} else {
if (widthExceeded) {
$(window).off('scroll', onScroll);
}
widthExceeded = false;
}
}).resize();
});
You are defining a scroll event listener inside a resize event listener, so basically you're declaring the scroll listener on every resive event (so the scroll listener is defined many many times if the user resize its browser). You need to correct this.
You could declare a flag (boolean) to indicate wether the viewport is below 725px or not. It should be initialized on $(document).ready(...) by testing the viewport dimensions.
Create a resize event listener which updates this flag by testing the viewport width, so you always know if you need to manage your classes or not.
At this point, console.log(your_flag) in your resize event listener to check if it works fine.
Then declare a scroll event listener, and in this listener the first thing you want to do is test the flag value. If viewport > 725, then manage the classes, otherwise do nothing.

Trigger jQuery mousemove event only once

I'm trying to make an exit popup and I could do that using the following code.
Whenever the user's mouse move out of the browser area, this gives a popup. But it is quite annoying when the popup comes everytime. I want to limit it to just a single time.
Can somebody help me with this?
jQuery(document).ready(function () {
jQuery(document).mousemove(function(e) {
jQuery('#exitpopup').css('left', (window.innerWidth/2 - jQuery('#exitpopup').width()/2));
jQuery('#exitpopup').css('top', (window.innerHeight/2 - jQuery('#exitpopup').height()/2));
if(e.pageY <= 5)
{
// Show the exit popup
jQuery('#exitpopup_bg').fadeIn();
jQuery('#exitpopup').fadeIn();
}
});
});
Use jQuery's one() function: http://api.jquery.com/one/
jQuery(document).ready(function () {
jQuery(document).one('mousemove', function(e) {
jQuery('#exitpopup').css('left', (window.innerWidth/2 - jQuery('#exitpopup').width()/2));
jQuery('#exitpopup').css('top', (window.innerHeight/2 - jQuery('#exitpopup').height()/2));
if(e.pageY <= 5)
{
// Show the exit popup
jQuery('#exitpopup_bg').fadeIn();
jQuery('#exitpopup').fadeIn();
}
});
});
Insert this:
e.stopPropagation();
just at the first list of the mousemouve function.
....
jQuery(document).mousemove(function(e) {
e.stopPropagation();
jQuery('#exitpopup').css('left', (window.innerWidth/2 - jQuery('#exitpopup').width()/2));
...
(function($) {
$(document).ready(function () {
var leftPage = false;
$(document).mousemove(function(e) {
if(e.pageY <= 5)
{
if (!leftPage) {
var exitPopup = $('#exitpopup');
exitPopup.css('left', (window.innerWidth/2 - exitPopup.width()/2));
exitPopup.css('top', (window.innerHeight/2 - exitPopup.height()/2));
$('#exitpopup_bg').fadeIn();
exitPopup.fadeIn();
}
leftPage = true;
} else {
leftPage = false;
}
});
});
})(jQuery);
"If the user leaves the page AND they have not already left THEN set popup. Next mark that they have left the page (leftPage = true)"
"Do not try and set the popup again until they are back in the page"
Couple of extras:
Instead of calling jQuery all the time we wrap the whole thing in a function wrapper so you can use $.
Instead of doing this everytime $('#exitpopup'); we CACHE it to a variable exitPopup so it doesn't have to do the lookup every time (inefficient)
A few things here. First, for form's sake, you should move your CSS alterations inside the if block, because you really don't need those to run every time the user moves their mouse, just right before you show the popup:
if(e.pageY <= 5)
{
// Alter CSS as appropriate
jQuery('#exitpopup').css('left', (window.innerWidth/2 - jQuery('#exitpopup').width()/2));
jQuery('#exitpopup').css('top', (window.innerHeight/2 - jQuery('#exitpopup').height()/2));
// Show the exit popup
jQuery('#exitpopup_bg').fadeIn();
jQuery('#exitpopup').fadeIn();
}
Second, you'll probably want to avoid showing it a second time by detaching the event handler. I'd recommend you use the jQuery .on() and .off() syntax instead of the shorthand .mousemove() because it'll be easier to read and maintain. I also recommend you use namespaces on your events so you can ensure that you're not detaching events that might have been set in other scripts.
jQuery(document).on('mousemove.yourNamespace', function (e) {
if(e.pageY <= 5)
{
// Alter CSS as appropriate
jQuery('#exitpopup').css('left', (window.innerWidth/2 - jQuery('#exitpopup').width()/2));
jQuery('#exitpopup').css('top', (window.innerHeight/2 - jQuery('#exitpopup').height()/2));
// Show the exit popup
jQuery('#exitpopup_bg').fadeIn();
jQuery('#exitpopup').fadeIn();
// now detach the event handler so it won't fire again
jQuery(document).off('mousemove.yourNamespace');
}
}
Lastly, if you wrap all of this code in an IIFE, you won't have to write out jQuery every time, and you still won't have to worry about possible conflicts with $ in the global namespace.
(function ($) {
$(document).on('mousemove.yourNamespace', function (e) {
if(e.pageY <= 5)
{
// Alter CSS as appropriate
$('#exitpopup').css('left', (window.innerWidth/2 - $('#exitpopup').width()/2));
$('#exitpopup').css('top', (window.innerHeight/2 - $('#exitpopup').height()/2));
// Show the exit popup
$('#exitpopup_bg').fadeIn();
$('#exitpopup').fadeIn();
// now detach the event handler so it won't fire again
$(document).off('mousemove.yourNamespace');
}
}
})(jQuery);
jQuery docs for .on(), .off(), and event.namespace for reference.

Jquery: How to check if input is focused

I am building a mobile web app where the page is set to responsive through screen width and height. I am facing one issue here. In a mobile, if I click any input field, the screen size changes due to mobile keypad in some browsers. In this case I don't want the screen to resize. Where as the screen has to resize when we rotate screen. Your help will be greatly appreciated. Below is the part of code I am using for that.
function pageresponsive() {
$('body').css('width', window.screen.width);
$('body').css('height', window.screen.height);
}
pageresponsive();
var input_click_status = 0;
$("input").click(function() {
input_click_status = 1;
});
$( "input" ).focus(function() {
input_click_status = 1;
});
//This might not work as resize event will be set at the time of page load
if(input_click_status == 0) {
$(window).resize(function() {
pageresponsive(true);
});
}
Try this solution
var isFocused = $("input").is(":focus")
for version 1.6+ of jquery
$("selector").is(":focus")
:Focus
you can check by two way:
you can bind an event on input.
var is_focused = false;
jQuery('input').bind('focus', function(){
is_focused = true;
/* you can write code what ever you want to do on focus.*/
});
or
there is one more function:
var is_focused = jQuery("input").is(":focus")

Is there a way to override the browser's default behavior for clicking on hashes?

When I have the following:
<a name='test'></a>
...and load it in a browser, I can append #test to the URL and the browser will scroll so that the <a> is at the top of the page.
However, I would like to change this behavior (using JavaScript if possible) so that using the hash does not scroll the page - I'd like it to simply do nothing.
Is there a way to do that without removing the <a> element?
Update: I need the browser to still send onhashchange() events but without scrolling to the <a> element. The reason being that I want to override the scrolling while retaining the event notification.
A quick dirty hack, but it's something you can build upon:
var curScroll = prevScroll = $(window).scrollTop()
$(window).bind('scroll', function() {
prevScroll = curScroll
curScroll = $(this).scrollTop()
}).bind('hashchange', function() {
$(this).scrollTop(prevScroll)
})
I used jQuery here to make it work across browsers and keep the page's onhashchange and onscroll handlers intact. One problem I spotted is that if you click the same hashtag twice it scrolls anyway.
UPD. I just figured out a better solution:
$('a').live('click', function() {
if (this.href.split('#')[0] == location.href.split('#')[0]) {
var scrollTop = $(window).scrollTop()
setTimeout(function() {
$(window).scrollTop(scrollTop)
}, 0)
}
})
Well, you can try to be brutal:
var i, elems = document.getElementsByTagName('a');
for (i = 0; i < elems.length; i++) {
elems[i].removeAttribute('name');
}
It has to be run after the DOM is ready but before it gets rendered so you have to put it in the right place. It won't work for 'id' attributes - only with <a name=...>
Does it do what you want?
Try this:
$( 'a[href="#"]' ).click( function(e) {
e.preventDefault();
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A kind-of hacky technique would be to just automatically scroll to the top of the page if there's a hash in the url:
if (window.location.hash) {
window.scrollTo(0, 0);
}
perhaps you need to use a bit of jquery and string manipulation
removeHashPartFromString = function() {
...
}
$('a').each(function() {
this.attr('href') = removeHashPartFromString(this.attr('href'));
});
Or find the elements with the hash and remove the name hash attributes from those elements.

Categories

Resources