0

I have the following jquery code that is aimed at running one function when the window is large (>=1024) and another when it is resized and small.

The console.logs appear as expected on resize, but the functions do not change. Meaning, if the browser was loaded in large size, when resized, the large function is still used.

(Resize code used from https://stackoverflow.com/a/4541963/1310375 and https://stackoverflow.com/a/9828919/1310375)

var waitForFinalEvent = (function () {
  var timers = {};
  return function (callback, ms, uniqueId) {
    if (!uniqueId) {
      uniqueId = "Don't call this twice without a uniqueId";
    }
    if (timers[uniqueId]) {
      clearTimeout (timers[uniqueId]);
    }
    timers[uniqueId] = setTimeout(callback, ms);
  };
})();

$(window).on('resize', function(){
  var win = $(this); //this = window

  waitForFinalEvent(function(){
  console.log('Resize...');

    if (win.width() >= 1024) { 
      console.log('large');

      $('.header-navigation-menu > div > ul > li').on({
        mouseenter: function() {
          console.log('waitEnterExit');
          waitEnterExit(this, true);
          $(this).children('.nav-menu-div').addClass('open');
        },
        mouseleave: function() {
          waitEnterExit(this, false);
        },
      });

      function waitEnterExit(el, inside) {
        var button = $(el);
        setTimeout(function() {
          var hovered = button.is(':hover');
          if (hovered && inside)
            button.children('.nav-menu-div').addClass('open');
          else if (!hovered && !inside)
            button.children('.nav-menu-div').removeClass('open');
        }, 500);
      }
    }

    if (win.width() <= 1023) { 
      console.log('small');

      $('.menu-link-button').on({
        click: function() {
          $(this).parent().children('.nav-menu-div').slideToggle();
        }
      });
    }
  }, 500);
});
Community
  • 1
  • 1
petergus
  • 1,192
  • 1
  • 12
  • 18
  • by "the functions" I assume you mean the various event handling functions that you are setting up? You'd have to use `.off()` to remove the unwanted event handlers. e.g. you do `$('.header-navigation-menu > div > ul > li').on` when the screen is large but you don't do anything to remove those handlers when the screen is small. – ADyson Apr 20 '17 at 09:51
  • The event handlers you attached to the elements of course _stay_ attached, they don’t magically disappear. You need to either remove them on resize - or check the window width _inside_ those event handlers again. – CBroe Apr 20 '17 at 09:51

1 Answers1

2

You are doing it in a wrong way, try the below steps and code,

First separate all functions and event bindings from window resize event. Then check window's width and toggle the elements which are to be hide(if visible)

function waitEnterExit(el, inside) {
  var button = $(el);
  setTimeout(function() {
    var hovered = button.is(':hover');
    if (hovered && inside)
      button.children('.nav-menu-div').addClass('open');
    else if (!hovered && !inside)
      button.children('.nav-menu-div').removeClass('open');
  }, 500);
}

$('.header-navigation-menu > div > ul > li').on({
  mouseenter: function() {
    console.log('waitEnterExit');
    var win = $(window);
    if (win.width() >= 1024) {
      console.log('large');
      waitEnterExit(this, true);
      $(this).children('.nav-menu-div').addClass('open');
    }
  },
  mouseleave: function() {
    if (win.width() >= 1024) {
      console.log('large');
      waitEnterExit(this, false);
    }
  },
});

$('.menu-link-button').on({
  click: function() {
    var win = $(window);
    if (win.width() <= 1023) {
      console.log('small');
      $(this).parent().children('.nav-menu-div').slideToggle();
    }
  }
});

$(window).on('resize', function() {
  var win = $(this); //this = window
  waitForFinalEvent(function() {
    if (win.width() >= 1024) {
      console.log('large');
      $('.menu-link-button').parent().children('.nav-menu-div').slideUp(); // hide it any way on large screen
    }  else {
      $('.header-navigation-menu > div > ul > li .nav-menu-div').removeClass('open'); // hide it in small screens
    }
    console.log('Resize...');
  }, 500);
});

If window>= 1024 and $('.menu-link-button') is sliding up again and again then check a condition for its visibility like

if (win.width() >= 1024) {
  console.log('large');
  $('.menu-link-button').parent().children('.nav-menu-div').is(':visible') // if visible then slideup
  &&
  $('.menu-link-button').parent().children('.nav-menu-div').slideUp(function(){ // hide it any way on large screen
      $(this).hide();/*make it hide after slide up*/
  });
}  else {
  $('.header-navigation-menu > div > ul > li .nav-menu-div').removeClass('open'); // hide it in small screens
}
Rohan Kumar
  • 40,431
  • 11
  • 76
  • 106
  • Thank you, that works! Maybe you can comment why, in the last section, resize, on every fresh page load it is triggered, and therefore since the page is more than 1024 the slideUp is triggered. – petergus Apr 20 '17 at 19:09
  • In your code `mouseenter` and `mouseleave` events were bind every time when you resize window and hence there were multiple element's sliding. Logically, you need to bind event once with certain window width condition, as done in my code. – Rohan Kumar Apr 21 '17 at 04:20
  • No what I mean is in `$(window).on('resize', function() {` whenever the window is loaded (or resized) and the size is over 1024 (no matter if it was previously smaller or not), `$('.menu-link-button').parent().children('.nav-menu-div').slideUp();` triggers. – petergus Apr 21 '17 at 05:55
  • 1
    It is because every time it triggers when window is resized, so first check its visibility, second you need to make it hide after slideUp(), so that it will not slide next time. Check my updated answer. – Rohan Kumar Apr 21 '17 at 06:23