Я встроил несколько iframe на свою веб-страницу. При прокрутке родительской страницы прокрутка останавливается и начинает пересылаться в iframe, как только на него наводится курсор мыши. Я знаю, что могу отключить события указателя в iframe, используя pointer-events: none, но мне нужно, чтобы iframe разрешал клики, игнорируя прокрутку.
Я контролирую как родительскую страницу, так и содержимое iframe. Есть ли какое-либо решение, как решить эту проблему с помощью атрибутов HTML в iframe, CSS или JavaScript?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете сделать что-то вроде этого:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title>Parent Page</title>
<style>
.iframe-container {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
}
.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
</style>
</head>
<body>
<!-- Parent Page Content -->
<div class = "iframe-container">
<iframe src = "iframe.html" id = "iframe"></iframe>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var iframe = document.getElementById('iframe');
// Event listener for scrolling on the parent page
window.addEventListener('scroll', function(event) {
// Check if the mouse is over the iframe
if (!isMouseOverIframe(event.clientX, event.clientY)) {
// Allow scrolling on the parent page
event.stopPropagation();
}
});
// Function to check if the mouse is over the iframe
function isMouseOverIframe(x, y) {
var rect = iframe.getBoundingClientRect();
return (
x >= rect.left &&
x <= rect.right &&
y >= rect.top &&
y <= rect.bottom
);
}
});
</script>
</body>
</html>
Элемент iframe имеет атрибут scrolling, которому можно установить значение no. Вот пример:
<iframe src = "https://www.bing.com/search?q=how+to+hide+scroll+bar+of+iframe&cvid=fdd706f4c38342ba9e208ec7334402db&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDsyBggCEEUYOTIGCAMQRRg7MgYIBBAAGEAyBggFEAAYQDIGCAYQRRg8MgYIBxBFGDwyBggIEEUYPNIBCDE4NzNqMGo0qAIAsAIA&FORM=ANAB01&PC=NMTS" scrolling = "no" height = "500px" width = "500px"></iframe>Просто не забудьте указать высоту и ширину, используя атрибуты iframe, чтобы избежать ошибок в CSS.
P.S на этот вопрос уже был дан ответ в этом посте.
Большое спасибо! Это выглядело очень многообещающе, но, к сожалению, оно устарело, и поэтому я не могу его использовать.
Без проблем! Кроме того, хотя валидатор W3C сообщает атрибут прокрутки = "no" как устаревший и рекомендует вместо него использовать CSS, это по-прежнему один из двух методов, которые могут помочь вам отключить прокрутку в большинстве браузеров. Другое решение — поставить style = "overflow: Hidden;" как атрибут элемента iframe.
Если допустимо, что пользователям приходится щелкать внутри iframe, прежде чем они смогут его прокручивать, вам может помочь следующий фрагмент:
Каждый iframe покрыт div одинаковой высоты и ширины, что защищает iframe от событий mousewheel. Обработчики событий click устанавливают отдельные пары iframe-div на scrollable: задавая высоту покрытия div 0, это позволяет событиям mousewheel достигать iframe.
Пара теряет scrollable, когда за ее пределами происходит щелчок.
Правило background-color дает визуальное представление о том, закрыт ли в данный момент iframe и, следовательно, его нельзя прокручивать.
document.querySelectorAll("div.iframe").forEach(function(div) {
div.addEventListener("click", function(event) {
div.classList.add("scrollable");
}, true);
});
document.addEventListener("click", function(event) {
document.querySelectorAll("div.iframe").forEach(function(div) {
div.classList.remove("scrollable");
});
}, true);div.iframe {
position: relative;
height: 100px;
}
div.iframe * {
position: absolute;
top: 0;
height: 100px;
width: 100%;
}
div.iframe div {
background-color: rgba(250, 250, 250, 0.5);
}
div.iframe.scrollable div {
height: 0;
}Page content
<div class = "iframe">
<iframe src = "first frame"></iframe>
<div></div>
</div>
More page content
<div class = "iframe">
<iframe src = "second frame"></iframe>
<div></div>
</div>Я предлагаю вам несколько разных подходов:
1. Наложение прозрачного Div: Поместите прозрачный элемент div поверх iframe. Этот div будет захватывать события мыши, позволяя прокручивать родительскую страницу, но при этом разрешать щелчки внутри iframe. Вот пример того, как это можно сделать с помощью CSS:
<style>
.iframe-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
background-color: rgba(0, 0, 0, 0);
}
</style>
<div class = "iframe-overlay"></div>
<iframe src = "your-iframe-source"></iframe>
При необходимости настройте класс .iframe-overlay в соответствии с вашим конкретным макетом.
Установить переполнение: скрыто для тела в Iframe (не перечисляя его в моем, поскольку кто-то уже предлагал это).
2. Обработка событий JavaScript: Используйте JavaScript для обработки событий мыши и управления поведением прокрутки. Когда мышь входит в iframe, отключите прокрутку на родительской странице. Когда мышь покинет iframe, снова включите прокрутку.
$(document).ready(function () {
const iframe = document.getElementById('your-iframe-id');
const parentBody = document.body;
iframe.addEventListener('mouseenter', () => {
parentBody.style.overflow = 'hidden';
});
iframe.addEventListener('mouseleave', () => {
parentBody.style.overflow = 'auto';
});
});
Это выглядит очень многообещающе, попробую сегодня вечером
Я реализовал метод решения этой проблемы, перехватив событие "wheel" в iframe, а затем используя postMessage() для передачи его родительскому окну, которое впоследствии вызывает scrollBy() со значением. Согласно моему тестированию, это также должно фиксировать события прокрутки с трекпада на ноутбуке. Если есть другие события, которые вы пытаетесь захватить, их тоже можно включить.
window.addEventListener("message", function(event){
window.scrollBy(0, event.data);
});body {height: 5000px; background-color: pink; color: black; font-weight: bold; font-family: sans-serif;}
iframe { width: 400px; height: 200px; border: 2px solid black; }<p>This parent window has a <code>"message"</code> event listener, and is calling <code>window.scrollBy(0, event.data)</code> with data from the iframe.</p>
<iframe src = "https://leodillon.com/resources/stackoverflow/iframe-scroll-passthru/iframe.html"></iframe>Я разместил iframe.html удаленно, так как не уверен, что есть другой способ опубликовать здесь рабочий фрагмент кода. Он содержит явскрипт:
window.addEventListener("wheel", function(event) {
event.preventDefault();
window.parent.postMessage(event.deltaY, "*");
}, {passive: false});
Когда я тестировал на трекпаде/ноутбуке, прокрутка на самом деле была очень плавной, поскольку, как я предполагаю, она вызывает множество мелких событий. При использовании колеса мыши, поскольку оно обычно работает в режиме «прыжка» при каждом щелчке колеса, оно будет прокручиваться поэтапно. Обычно они сглаживаются браузером при непосредственной обработке ввода с помощью колесика, однако я считаю, что с помощью этого метода вам придется реализовать плавную прокрутку самостоятельно, если это необходимо. Но это не так уж и неудобно, поскольку он по-прежнему прокручивается с нормальной общей скоростью, которую вы ожидаете!
Обратите внимание, что passive: false также установлен в прослушивателе событий; вы можете подумать, что это значение по умолчанию, но это НЕ для "wheel" и пары других событий, в частности!
Если вы иным образом используете обмен сообщениями в своем приложении, вам, конечно, нужно будет оформить это как определенный тип сообщения для обработки таким образом.
Это абсолютно сработало, и мне нравится ситуация. Спасибо!
Спасибо! Это похоже на то, что я пробовал раньше. В настоящее время я использую трекпад и безуспешно. Я также сделал пассивным прослушиватель событий, но я все равно могу прокручивать. В настоящее время ведется отладка, иначе есть идеи, что может быть причиной того, что прокрутка все еще происходит?