Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Change hover to click function after resize screen

I hope $(".menu-item-has-children").hover(...); works when screen width >= 768, and $(".menu-item-has-children").click(...) works when screen width < 768.

I try to use resize() to check if the screen width larger than 768px.

The problem is when I open the page with the screen width over 768px, then resize it under 768px, the hover() function still work.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How do I make the hover function works only when screen width > 768px ?

let show = function () {
    try {
      clearTimeout(leavetimer);
    } catch {}
    entertimer = setTimeout(() => {
      $(this).find("ul").addClass("active");
    }, 400);
  },
  hide = function () {
    clearTimeout(entertimer);
    leavetimer = setTimeout(() => {
      $(this).find("ul").removeClass("active");
    }, 400);
  },
  large = $(window).width() >= 768;
$(window)
  .resize(function () {
    large = $(window).width() >= 768;
  })
  .resize();

$(document).ready(() => {
  if (large) {
    $(".menu-item-has-children").hover(show, hide);
  } else {
    $(".menu-item-has-children").click(function () {
      if (!$(this).find("ul").hasClass("active")) {
        $(this).find("ul").addClass("active");
      } else {
        $(this).find("ul").removeClass("active");
      }
    });
  }
});
.menu-item-has-children ul {
  display: none;
}
.menu-item-has-children ul.active {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav-bar">
    <li class="menu-item-has-children"><a>class 1</a>
        <ul class="sub-menu">
            <li><a href="#">child 1</a></li>
            <li><a href="#">child 2</a></li>
            <li><a href="#">child 3</a></li>
            <li><a href="#">child 4</a></li>
            <li><a href="#">child 5</a></li>
        </ul>
    </li>
    <li><a href="#">class 2</a></li>
</ul>

>Solution :

The browser executes your document.ready block exactly once, on the initial page load. Resizing happens after the initial code has executed – your resize event is there, but you haven’t told the browser what to do with it yet. You need to apply the logic to the event listener for the resize event, binding and unbinding click/mouseenter/mouseleave event listeners.

Note: Since the event logic is used by two seperate listeners, you can put it in a seperate function. I left that up to you. DNRY! 🙂

let show = function () {
    try {
      clearTimeout(leavetimer);
    } catch {}
    entertimer = setTimeout(() => {
      $(this).find("ul").addClass("active");
    }, 400);
  },
  hide = function () {
    clearTimeout(entertimer);
    leavetimer = setTimeout(() => {
      $(this).find("ul").removeClass("active");
    }, 400);
  },
  large = $(window).width() >= 768;
$(window).resize(function () {
    large = $(window).width() >= 768;
    if (large) {
      // remove previously applied listener
      $(".menu-item-has-children").off('click');
      $(".menu-item-has-children").hover(show, hide);
    } else {
      // equals to hover(). I suggest using .on('...') instead of .hover()
      $(".menu-item-has-children").off('mouseenter mouseleave');
      $(".menu-item-has-children").click(function () {
        if (!$(this).find("ul").hasClass("active")) {
          $(this).find("ul").addClass("active");
        } else {
          $(this).find("ul").removeClass("active");
        }
      });
    }
  });

$(document).ready(() => {
  if (large) {
    $(".menu-item-has-children").hover(show, hide);
  } else {
    $(".menu-item-has-children").click(function () {
      if (!$(this).find("ul").hasClass("active")) {
        $(this).find("ul").addClass("active");
      } else {
        $(this).find("ul").removeClass("active");
      }
    });
  }
});
.menu-item-has-children ul {
  display: none;
}
.menu-item-has-children ul.active {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav-bar">
    <li class="menu-item-has-children"><a>class 1</a>
        <ul class="sub-menu">
            <li><a href="#">child 1</a></li>
            <li><a href="#">child 2</a></li>
            <li><a href="#">child 3</a></li>
            <li><a href="#">child 4</a></li>
            <li><a href="#">child 5</a></li>
        </ul>
    </li>
    <li><a href="#">class 2</a></li>
</ul>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading