Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

168
Vistas
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.

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>

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

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>

about 4 years ago · Juan Pablo Isaza Denunciar

0

here is my way to achieve this with common function

var entertimer;
var leavetimer;

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

$(window).resize(function () {
  large = $(window).width() >= 768;
  change();
}).resize();

$(document).ready(() => {
  change();
});

function change() {
  if (large) {
    $(".menu-item-has-children").hover(show, hide);
    $(".menu-item-has-children").unbind('click');
  } else {
    $(".menu-item-has-children").unbind('click');
    $(".menu-item-has-children").click(function () {
      $(".menu-item-has-children").unbind('mouseenter mouseleave');
      console.log('$(this).find("ul")', $(this).find("ul"))
      if (!$(this).find("ul").hasClass("active")) {
        $(this).find("ul").addClass("active");
      } else {
        $(this).find("ul").removeClass("active");
      }
    });

  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <style>
    .menu-item-has-children ul {
  display: none;
}
.menu-item-has-children ul.active {
  display: block;
}
  </style>
</head>

<body>
  <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>
</body>

</html>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda