jQuery 基于模态可见性设置元素样式在 Firefox 和 Chrome 中表现不同

jQuery Setting Element Styles Based On Modal Visibility Behaves Differently in Firefox and Chrome

我是 jquery 和 javascript 的新手。我有一个网站,其中包含多个唯一 modal/popups,这些 modal/popups 通过 CSS :target 选择器触发,将它们设置为 display: block。我正在尝试使用 jquery 来隐藏一个单独的元素。

逻辑是:
如果模式可见,则隐藏元素。否则显示元素。我目前在 jquery 中使用 popstate。这是因为如果用户按下浏览器后退按钮,模态框就会关闭。所以我不想使用任何点击功能。一切似乎都工作正常,除了检测模式可见性的 if/else 语句在 Firefox 和 Chrome 之间似乎表现不同?当它在 Firefox 中隐藏该元素时,它会显示它 Chrome。当它隐藏在 Chrome 中时,它会在 Firefox 中显示。为什么相反的行为?我做错了什么?

$(window).on('popstate', function(event) {
  if ($('.modal').is(':visible')) {
    console.log("Modal ON");
    $('#wrapper').css('overflow-y', 'hidden');
    $('#extra_element').css('display', 'none');
  } else {
    console.log("Modal OFF");
    $('#wrapper').css('overflow-y', 'scroll');
    $('#extra_element').css('display', 'block');
  }
});
.modal {
  display: none;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 0 auto;
}

.modal:target {
  display: block;
}

#extra_element {
  width: 100vw;
  height: 20vh;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="extra_element">This element should hide when modal is open</div>

<div>
  <a href="#content">Click Me To Open Modal</a>
  <div id="content" class="modal">I'm a Modal. Press browser back button to close 
  </div>
</div>

候补 jQuery:

将长度设置为 1 在 Firefox 中有效,在 Chrome 中相反。
将长度设置为 0 在 Chrome 中有效,在 Firefox 中相反。

$(window).on('popstate', function(event) {
    if ( $('.modal-overlay:visible').length === 1 ) {
        console.log("Modal ON");
        $('#wrapper').css('overflow-y', 'hidden');
        $('#extra_element').css('display', 'none');
    }
    else {
        console.log("Modal OFF");
        $('#wrapper').css('overflow-y', 'scroll');
        $('#extra_element').css('display', 'block');
    }
});

还有其他正确的方法吗?

根据 the specs, at the step 10 of the History traversal algorithm the UA should call the "scroll to fragment" algorithm which is responsible for updating the document's target element (:target),这将是一个 Chrome 错误,只有在第 18.1 步它应该触发 popstate 事件。
Chrome 会在更新文档的 目标元素 之前触发事件,因此您的 CSS :target 选择器还不匹配。
did open an issue 所以他们 in-line 符合标准,但目前你可以通过在事件触发后等待一个任务来解决这个问题:

$(window).on('popstate', async function(event) {
  await new Promise(res => setTimeout(() => res()));
  if ($('.modal').is(':visible')) {
    console.log("Modal ON");
    $('#wrapper').css('overflow-y', 'hidden');
    $('#extra_element').css('display', 'none');
  } else {
    console.log("Modal OFF");
    $('#wrapper').css('overflow-y', 'scroll');
    $('#extra_element').css('display', 'block');
  }
});
.modal {
  display: none;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 0 auto;
}

.modal:target {
  display: block;
}

#extra_element {
  width: 100vw;
  height: 20vh;
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="extra_element">This element should hide when modal is open</div>

<div>
  <a href="#content">Click Me To Open Modal</a>
  <div id="content" class="modal">Press browser back button to close 
  </div>
</div>