How to use jquery resize run funtion one time? - javascript

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

Related

Click doesn't work correctly after append

My code generates an infinite scroll but when I touch each one it appears alerts many times and that isn't right.
$(window).scroll(function() {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
var variable = "<div class='corazon'>hi</div>";
$(".hola").append(variable);
$('.corazon').on('click', function() {
alert("hola");
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Thank you.
$('.corazon').on('click', function() {
alert("hola");
});
You're adding a new click listener to all the elements with class "corazon" every time you reach the scroll limit.
You should add the click listener on the created element instead of performing a new query $(".corazon") .
Try this:
var variable = $("<div class='corazon'>hi</div>");
$(".hola").append(variable);
variable.on('click', function() {
alert("hola");
});
This has already been asked, use jquery clone to clone an existing element with listener.
.clone( [withDataAndEvents ] [, deepWithDataAndEvents ] )
Provide both with true.
And yes
$('.corazon').on('click', function(){
alert("hola");
});
Should not be in the scoll listener
Full documentation: https://api.jquery.com/clone/
Instead of:
$('.corazon').on('click', function() {
you shuld have:
$(variable ).on('click', function() {
Now the clickhandler is only added to the new element.

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.

Dynamically add class on browser resize (viewport width)

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

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.

Using JQuery on and off method to attach and remove selected event handlers

I'm using JQuery on method to attach an event handler to the window object:
$(window).on('resize', function(e){
/** my functional code goes here **/
e.stopPropagation();
});
This is event handler is being called multiple times: The reason this is so is because the event handler is in the initialization section of a JQuery plugin, so when someone calls the plugin constructor like so:
$('selector').myPlugin({settings_1});
$('selector').myPlugin({settings_2});
$('selector').myPlugin({settings_3});
The event handler gets attached 3 times.
I'm looking for a way to identify and decommission all but one of the 3 event handlers (using off method) so that during a resize, only one of them will get triggered.
How do I identify the event handlers and remove the ones I want?
Try this:
function myHandler(e){
/** my functional code goes here **/
e.stopPropagation();
}
$(window).on('resize', function (e){
$(window).off('resize', myHandler);
$(window).on('resize', myHandler);
});
If your event handlers have been attached only with jquery (not with plain javascript), read the answer to this question to check if a DOM element already has an event handler and, in your case, avoid duplicating it.
You can leverage an array of {key, callback}. Something like this:
window.resizeCallbacks = [];
function addResizeCallback(key, callback) {
window.resizeCallbacks.push({
key: key,
callback: callback
});
}
function removeResizeCallback(key) {
var index = -1;
for (var i = 0; i < window.resizeCallbacks.length; i++) {
if (window.resizeCallbacks[i].key === key) {
index = i;
}
}
if (index >= 0) {
window.resizeCallbacks.splice(index, 1);
}
}
$(function() {
$(window).resize(function() {
for (var i = 0; i < window.resizeCallbacks.length; i++) {
window.resizeCallbacks[i].callback();
}
});
});

Categories

Resources