DOM滚动(touchmove)事件,如何找到哪个元素滚动了

问题描述 投票:0回答:3

这是有点做作的代码:

 function h (evt) {
   if(evt.target.nodeName !=== 'POPUP') {
       evt.preventDefault()
   }
 }
 window.addEventListener('DOMMouseScroll', h, false)
 window.addEventListener('wheel', h, false)

它在这里试图实现的是阻止页面上的所有其他滚动,除了打开弹出窗口时在弹出窗口内滚动。 但这不起作用,因为

evt.target
包含当前由鼠标指向的元素,而不是实际滚动的元素。因此,要么整个页面滚动,要么只是弹出内容,但在这两种情况下,
evt.target
都将指向弹出窗口内的某个按钮。

但我们的想法是获取现在实际滚动的内容,页面主体或弹出窗口。

https://jsfiddle.net/zr9hjL4s/1/

javascript html dom
3个回答
2
投票

要解决此问题,您可以尝试不同的方法。您可以检查目标元素的滚动容器是主体还是弹出窗口。

示例

function h (evt) {
   var currentElement = evt.target;
   while(currentElement) {
       if(currentElement === document.body) {
           evt.preventDefault();
           break;
       }
       if(currentElement.nodeName === 'POPUP') {
           break;
       }
       currentElement = currentElement.parentNode;
   }
}

window.addEventListener('DOMMouseScroll', h, false);
window.addEventListener('wheel', h, false);

编辑-另一个版本

所以根据我的理解,可能有多个嵌套的可滚动元素。为了处理这种情况,我将使用

Element.scrollWidth
Element.scrollHeight
属性。如果一个元素的
scrollWidth
/
scrollHeight
大于它的
clientWidth
/
clientHeight
,那么它就是一个可滚动元素。

我也尝试了你的 jsfiddle,它似乎工作正常 - 也许我错过了一些东西 - 更多解释会很有用。

function h (evt) {
   var currentElement = evt.target;
   while(currentElement && currentElement !== document.body) {
       if(currentElement.nodeName === 'POPUP' || isScrollable(currentElement)) {
           break;
       }
       currentElement = currentElement.parentNode;
   }

   if(currentElement === document.body || !currentElement) {
       evt.preventDefault();
   }
}

function isScrollable(el) {
    return (el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth);
}

window.addEventListener('DOMMouseScroll', h, false);
window.addEventListener('wheel', h, false);

0
投票

要实现阻止整个页面滚动(打开弹出窗口除外)所需的行为,您可以修改事件侦听器和 PreventDefault 函数。您可以检查触发滚动事件的元素是否位于弹出窗口内,而不是仅仅依赖

evt.target
属性。这是更新后的代码:

h
函数中,检查目标元素或其任何父元素是否具有“scroll”类(代表弹出窗口)。如果是,则允许滚动;否则,阻止默认滚动行为:

function h(evt) {
  const targetElement = evt.target;
  if (!targetElement.closest('.scroll')) {
    evt.preventDefault();
  }
}

当您打开弹出窗口时,请确保调用disableScrollExcept函数并传递弹出窗口元素:

function dis() {
  let e = document.getElementById('scroll');
  disableScrollExcept(e);
}

通过这些更改,当弹出窗口打开并且您尝试在其中滚动时,将允许滚动。当您尝试滚动到弹出窗口之外时,默认的滚动行为将被阻止。这样,您就可以实现所需的滚动行为。


0
投票

似乎这里的技巧是与 js 动态代码一起工作,以停止传播并防止滚动的默认行为,再加上 css 代码来隐藏允许浏览器在元素上滚动的溢出功能。因此,首先要考虑的是,一旦打开模式,在这种情况下,您需要禁用整个页面(主体)的滚动,不确定您的页面在实际场景中是如何构建的,但在这种情况下,我们有一个通过打开的经典模式通过添加模态打开的状态类型并在关闭模态后删除该类来修改 Node.js。使用js函数openModal打开模态框。在提供的示例中,我在执行整个 js 代码后运行此函数。所以模态会立即提示。还要检查模态内容内部是否使用了 CSS 规则“overflow-y”,以使“内部”可滚动。

取决于您的需求。您可以使用代码并适应您的要求,但这段代码过去曾多次救过我。 :D 希望这有帮助。

const modalContainer = document.getElementById('modal-container');
const modalContent = document.getElementById('modal-content');

function openModal() {
  modalContainer.style.display = 'block';
  document.body.classList.add('modal-open');
  document.body.addEventListener('scroll', disableScroll);
}

function closeModal() {
  modalContainer.style.display = 'none';
  document.body.classList.remove('modal-open');
  document.body.removeEventListener('scroll', disableScroll);
}

modalContainer.addEventListener('click', (event) => {
  if (event.target === modalContainer) {
    closeModal();
  }
});

// Optional: Close the modal when the Escape key is pressed
document.addEventListener('keydown', (event) => {
  if (event.key === 'Escape') {
    closeModal();
  }
});

function disableScroll(event) {
  event.preventDefault();
  event.stopPropagation();
}

openModal()
.modal-container {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.8);
  z-index: 9999;
  overflow: hidden;
}

.modal-content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 80%;
  max-height: 80%;
  padding: 20px;
  background-color: white;
  border-radius: 10px;
  overflow-y: auto; 
}

body.modal-open {
  overflow: hidden; 
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Modal Window</title>
</head>
<body>
  <!-- Your page content goes here -->
  <div>
  What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.
   
   <br/>
   What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.

  </div>
  <!-- Modal Container -->
  <div id="modal-container" class="modal-container">
    <div id="modal-content" class="modal-content">
      <!-- Your modal content goes here -->
      <h2>Modal Window</h2>
      <p>Scroll me!!!</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.<br/>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.<br/>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.<br/>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.<br/>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod purus ut facilisis elementum.</p>
      <!-- End of modal content -->
    </div>
  </div>

  <!-- End of page content -->
  <div>
  What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.
   
   <br/>
   What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.

  <br/>
   What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.

 <br/>
   What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.

 <br/>
   What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.<br/>
What it tries to achieve here is to prevent all other scrolling on the page, except inside popup when popup is opened. But this doesn't work because evt.target contains element currently pointed by mouse rather than one that actually scrolled. So either the whole page would be scrolled or just popup conents, but in both cases evt.target will point to some button inside popup.

But the idea is to get what got actually scrolled now, page body or popup.

  </div>
</body>
</html>

https://jsfiddle.net/web20opensource/14zp6btL/1/

© www.soinside.com 2019 - 2024. All rights reserved.