Как принимать клики в iframe, но игнорировать прокрутку с родительской страницы

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

Я контролирую как родительскую страницу, так и содержимое iframe. Есть ли какое-либо решение, как решить эту проблему с помощью атрибутов HTML в iframe, CSS или JavaScript?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
276
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете сделать что-то вроде этого:

<!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>

Спасибо! Это похоже на то, что я пробовал раньше. В настоящее время я использую трекпад и безуспешно. Я также сделал пассивным прослушиватель событий, но я все равно могу прокручивать. В настоящее время ведется отладка, иначе есть идеи, что может быть причиной того, что прокрутка все еще происходит?

HelloWorld 21.04.2024 20:34

Элемент 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 на этот вопрос уже был дан ответ в этом посте.

Большое спасибо! Это выглядело очень многообещающе, но, к сожалению, оно устарело, и поэтому я не могу его использовать.

HelloWorld 26.04.2024 22:21

Без проблем! Кроме того, хотя валидатор W3C сообщает атрибут прокрутки = "no" как устаревший и рекомендует вместо него использовать CSS, это по-прежнему один из двух методов, которые могут помочь вам отключить прокрутку в большинстве браузеров. Другое решение — поставить style = "overflow: Hidden;" как атрибут элемента iframe.

Mulham Alamry 27.04.2024 11:06

Если допустимо, что пользователям приходится щелкать внутри 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';
  });
});

Это выглядит очень многообещающе, попробую сегодня вечером

HelloWorld 26.04.2024 22:23
Ответ принят как подходящий

Я реализовал метод решения этой проблемы, перехватив событие "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" и пары других событий, в частности!

Если вы иным образом используете обмен сообщениями в своем приложении, вам, конечно, нужно будет оформить это как определенный тип сообщения для обработки таким образом.

Это абсолютно сработало, и мне нравится ситуация. Спасибо!

HelloWorld 30.04.2024 05:23

Другие вопросы по теме