jquery window 调整大小功能只触发一次而不是每次调整大小时触发

jquery window resize function only triggering once instead of at every resize

我正在尝试设置一个 jquery 函数来检查 window 宽度以使导航栏正常工作。我想要发生的是这样的:如果屏幕宽度 大于 大于 949px,启动一个函数,使鼠标悬停在 .dropdown 锚 link 上打开一个下拉子菜单;如果屏幕宽度 小于或等于 949px,请删除该功能,以便必须单击 .dropdown 锚点 link 才能打开下拉子菜单 (单击它们时,下拉菜单 link 默认打开 - 我认为这是一个 bootstrap 组件)。

我根据我在 Whosebug 上找到的一些类似示例创建了一些函数,但发现该函数仅在屏幕宽度超过 949px 时触发,因此在较小的宽度下,.dropdown 锚点仍会通过悬停打开子菜单是我不想要的。

var width = $(window).width();
$(window).resize(function(){
  if($(this).width()>949){
    $(".dropdown").hover(function(){
      $(this).addClass("open");
    },
    function(){
      $(this).removeClass("open");
    });
  }
});

我如何改进此功能,以便在宽度大于 949px 时添加 .dropdown 悬停功能并在宽度小于 949px 时删除?

可能并不完美,因为 jquery 不是我的强项,但它可以做到:

var width = $(window).width();
$(window).resize(function(){
  if($(this).width()>949){
    $(".dropdown").on({
        mouseenter: function () {
            $(this).addClass("open");
        },
        mouseleave: function () {
            $(this).removeClass("open");
        }
    });
  }
  else{
    $(".dropdown").off("mouseenter");
    $(".dropdown").off("mouseleave");
  }
});

请注意,此实现还将删除 .dropdown 元素上的任何其他现有 mouseenter 和 mouseleave 事件处理程序。

无需添加和删除绑定,只需建立事件绑定并在执行任何操作之前检查大小:

$(".dropdown").hover(function() {
    if ($(window).width() > 949) {
        $(this).addClass("open");
    }
}, function() {
    if ($(window).width() > 949) {
        $(this).removeClass("open");
    }
});

如果您添加和删除事件处理程序,您需要防止执行两次(例如,它们将大小调整为 980,然后调整为 1050)。

var hover_added = false;

$(window).resize(function() {
    var width = $(this).width();
    if (width > 949 && !hover_added) {
        $(".dropdown").on({
            mouseenter: function () {
                $(this).addClass("open");
            },
            mouseleave: function () {
                $(this).removeClass("open");
            }
        });
        hover_added = true;
    } else if (width <= 949 && hover_added) {
        $(".dropdown").off("mouseenter mouseleave");
        hover_added = false;
    }
});

我的建议是(为了避免同一个事件绑定多次):

var width = $(window).width();

$(window).on('resize', function(e) {
  doResize(e);
});

function doResize(e) {
  if ($(this).width()>949) {
    var isOpenOnHover = $('.dropdown-toggle').data('isOpenOnHover');
    if (isOpenOnHover) {
      return;
    }
    $('.dropdown-toggle').data('isOpenOnHover', true);
    $('.dropdown-toggle').hover(function () {
      $('.dropdown-toggle').trigger('click.bs.dropdown');
    });
  } else {
    $('.dropdown-toggle').data('isOpenOnHover', false);
    $('.dropdown-toggle').off('mouseenter mouseleave');
  }
}

$(function () {
  $('.dropdown-toggle').data('isOpenOnHover', false);
  doResize();
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>



<div class="bs-example">
    <div class="dropdown">
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">Dropdown <b class="caret"></b></a>
        <ul class="dropdown-menu">
            <li><a href="#">Action</a></li>
            <li><a href="#">Another action</a></li>
        </ul>
    </div>
</div>