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>
我是 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>