开发者问题收集

如果元素可见,则单击空白区域并运行函数

2022-08-30
115

单击 html 主体时: 如果元素“#cap”可见,则执行某些操作。 如果元素“#cap”由于滚动过去而不可见,则执行其他操作。

我尝试了 @Heretic Monkey 的建议,并将函数移至 js 文件的底部,但根本不起作用。

应版主的要求,我声明我尝试了 @Heretic Monkey 的建议,并将函数移至 js 文件的底部,但根本不起作用。

<thead id = 'cap'>
function isInViewport(el) {
  rect = el.getBoundingClientRect();
  return (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight ||
    document.documentElement.clientHeight) && rect.right <= (window.innerWidth ||
    document.documentElement.clientWidth));
}

box = document.querySelector('#cap');
document.addEventListener('click', function() {
  if (isInViewport(box)) {
    alert('true');
  } else {
    alert('false');
  }
});

Chrome 控制台显示:blank.js:3 未捕获 TypeError:无法读取 null 的属性(读取“getBoundingClientRect”)

function isInViewport(el) {rect = el.getBoundingClientRect();

有人可以解释为什么此代码除了产生控制台错误外什么也不做吗?

3个回答

您可以使用 IntersectionObserver 来告诉您元素是否在视图中。您可以使用目标来确定点击发生的位置。

let isIntersecting;

var observer = new IntersectionObserver(onIntersection, {
  root: null,
  threshold: .5,
})

function onIntersection(entries, opts) {
  isIntersecting = entries[0].isIntersecting;
}

observer.observe(document.querySelector('#thead'));

window.addEventListener("click", function (e) {
  if (e.target.closest("table")) return;
  console.log('Table not clicked and the header is', isIntersecting ? "visible" : "not visible");
});
table tr td {
  border: 1px solid black;
}
<table>
  <thead id="thead">
    <tr>
      <td>Header</td>
    </tr>
  </thead>
  <tbody>
    <tr><td>1</td></tr>
    <tr><td>2</td></tr>
    <tr><td>3</td></tr>
    <tr><td>4</td></tr>
    <tr><td>5</td></tr>
    <tr><td>6</td></tr>
    <tr><td>7</td></tr>
    <tr><td>8</td></tr>
    <tr><td>9</td></tr>
    <tr><td>10</td></tr>
    <tr><td>11</td></tr>
    <tr><td>12</td></tr>
    <tr><td>13</td></tr>
    <tr><td>14</td></tr>
    <tr><td>15</td></tr>
    <tr><td>16</td></tr>
    <tr><td>17</td></tr>
    <tr><td>18</td></tr>
    <tr><td>19</td></tr>
    <tr><td>20</td></tr>
    <tr><td>21</td></tr>
    <tr><td>22</td></tr>
    <tr><td>23</td></tr>
    <tr><td>24</td></tr>
    <tr><td>25</td></tr>
    <tr><td>26</td></tr>
    <tr><td>27</td></tr>
    <tr><td>28</td></tr>
    <tr><td>29</td></tr>    
  </tbody>  
</table>
epascarello
2022-08-31

该元素未出现在 DOM 中,请在添加点击事件之前 检查 DOM 是否处于就绪状态

function isInViewport(el) {
  rect = el.getBoundingClientRect();
  return (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight ||
    document.documentElement.clientHeight) && rect.right <= (window.innerWidth ||
    document.documentElement.clientWidth));
}

document.addEventListener('DOMContentLoaded', function() {
    document.addEventListener('click', function() {
        box = document.querySelector('#cap');
        if (isInViewport(box)) {
            alert('true');
        } else {
            alert('false');
        }
    });
});
function isInViewport(el) {
  rect = el.getBoundingClientRect();
  return (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight ||
    document.documentElement.clientHeight) && rect.right <= (window.innerWidth ||
    document.documentElement.clientWidth));
}

document.addEventListener('DOMContentLoaded', function() {
    document.addEventListener('click', function() {
        box = document.querySelector('#cap');
        if (isInViewport(box)) {
            alert('true');
        } else {
            alert('false');
        }
    });
});
<div id="cap"></div>
Andrés Andrade
2022-08-30

我原来的代码是正确且足够的。我只是创建并定位了两个具有绝对位置的大型可点击 div。而不是监听 body 点击。

<div id = 'left_div' onclick = 'ring ();'></div>
<div id = 'right_riv onclick = 'ring ();'></div>

function isInViewport(el) {
 rect = el.getBoundingClientRect();
 return (rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight ||
 document.documentElement.clientHeight) && rect.right <= (window.innerWidth ||
 document.documentElement.clientWidth));
}

function ring() {
box = document.querySelector('#cap');
document.addEventListener('click', function() {
if (isInViewport(box)) {stone();} else {rock();}
});}
verlager
2022-09-02