【问题标题】:Remove event listener and reset classList toggle on resize删除事件侦听器并在调整大小时重置 classList 切换
【发布时间】:2019-06-23 20:31:46
【问题描述】:

我想在调整浏览器大小的同时移除特定屏幕尺寸上的点击事件监听器。

问题是下面的代码在我刷新页面的地方有效,并且需要的结果就在那里。但是,在调整浏览器大小时,它会保持在低于所需宽度时可点击或超过所需宽度时不可点击的状态。

let viewPort = window.innerWidth || document.documentElement.clientWidth;
let dropToggle = document.querySelectorAll(".someparent");
let dropMenu = document.querySelectorAll(".somechild");

for (let i = 0; i < dropToggle.length; i++) {
  dropToggle[i].addEventListener('click', function a(event) {
    if (viewPort < 786) {
      dropMenu[i].classList.toggle("drop");
      if (event.dropToggle == 2);
      event.stopPropagation();
    }
    else {
      dropToggle.removeEventListener('click', a);
      /*update*/
      dropMenu[i].classList.remove("drop");
    }
    /*update*/
    window.addEventListener("resize", function() {
     viewPort = window.innerWidth || document.documentElement.clientWidth;
    }, true);
  });
}

所以基本上,我需要在调整浏览器大小而不刷新页面的情况下启动该功能。任何帮助将不胜感激。

EDIT 使用部分解决方案更新了代码。

新问题: 切换 classList.toggle “drop”如果未在较小宽度上关闭,则保持打开状态。将 classList.remove 添加到 else 条件中的“drop”也不起作用,这实际上会在调整大小时完全删除该函数。有没有办法在调整大小时重置 classList.toggle?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    每次调整窗口大小时,您都需要更新viewPort 的值。目前viewPort 在您加载页面时被初始化,但永远不会再次重新初始化。为此,您可以将resize 事件侦听器添加到您的window

    window.addEventListener("resize", function() {
      viewPort = window.innerWidth || document.documentElement.clientWidth;
    }, true);
    

    【讨论】:

    • 这成功了,把它放在 else 条件之后,谢谢!但是,我遇到了另一个问题;如果我单击以将其从较小的尺寸打开,然后将其调整为较大的宽度,它会保持打开状态。所以我尝试添加: dropMenu[i].classList.remove("drop");在 else 条件下但不起作用,它会一起删除调整大小的功能。关于如何改进这一点的任何想法?
    • @thx1138 我原以为这会起作用,所以它不起作用似乎很奇怪/您可以编辑您的问题以显示您尝试关闭菜单的操作
    • 这里也一样。普通用户在访问网站时不会疯狂地调整浏览器的大小。我可以保持原样,但是,这可能不是一个好主意,尤其是出于测试目的。同样是的,问题已更新。
    • @thx1138 您能否在jsfiddle 中重新创建问题的较小版本。如果你这样做,我可以帮助调试得更好
    • 对不起,我需要弄清楚为什么它在 jsfiddle 中不起作用。现在,是的,将该功能从循环中取出已经取得了一些进展,点击功能仍然存在,但在调整大小时仍会打开该项目。我会尝试其他解决方案并发布有效的代码,感谢您的帮助!
    【解决方案2】:

    您需要在 for 循环之外定义事件侦听器调用 & 将回调作为添加/删除事件侦听器方法中的引用传递。

    另外还需要添加window.resize事件监听器(如下图)

    这段代码应该适合你

    let dropToggle = document.querySelectorAll(".someparent");
    let dropMenu = document.querySelectorAll(".somechild");
    
    function a(event) {
        dropMenu[i].classList.toggle("drop");
        if (event.dropToggle == 2);
        event.stopPropagation();
    }
    
    for (let i = 0; i < dropToggle.length; i++) {
        window.addEventListener("resize", function() {
            viewPort = window.innerWidth || document.documentElement.clientWidth;
            if (viewPort < 786) {
                dropToggle[i].addEventListener("click", a);
            } else {
                dropToggle[i].removeEventListener("click", a);
            }
        });
    
    }
    

    【讨论】:

      【解决方案3】:

      Matchmedia 可以处理这个问题 - 并在媒体(窗口)符合条件时允许使用 javascript 函数。

      可以在此处 (https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) 和此处 (https://www.sitepoint.com/javascript-media-queries/) 找到参考资料

      实际上是它对 javascript 的媒体查询。语法与 CSS 媒体查询基本相同。

      // media query event handler
      if (matchMedia) {
        const mq = window.matchMedia("(min-width: 768px)");
        mq.addListener(WidthChange);
        WidthChange(mq);
      }
      
      // media query change
      function WidthChange(mq) {
        if (mq.matches) {
          // do what you want when  window width is at least 768px
        } else {
          // do what you want when window width is less than 768px
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-03-31
        • 1970-01-01
        • 2018-09-04
        • 1970-01-01
        • 1970-01-01
        • 2012-06-02
        • 1970-01-01
        • 2012-03-24
        相关资源
        最近更新 更多