JS检测元素是否在视图窗口内
既然我们知道如何获取浏览器窗口的尺寸,自然的下一步就是将 innerWidth 和 innerHeight 属性与 getBoundingClientRect 结合使用来检测元素当前是否在用户视图中。
getBoundingClientRect 方法返回一个对象,其中包含我们正在检查的元素的位置。
为了在滚动时工作,我们需要为滚动事件设置一个事件监听器:
let h1 = document.querySelector('h1'); let firstInView = false; document.addEventListener('scroll', inView); function inView() { let bounding = h1.getBoundingClientRect(); if (bounding.top >= 0 && bounding.left >= 0 && bounding.right <= window.innerWidth && bounding.bottom <= window.innerHeight) { if (false === firstInView) { console.log('The element was in the view.'); firstInView = true; } } else { console.log('Element not in view'); firstInView = false; } }
firstInView 变量确保当元素在视口中时我们想要执行的任何操作只执行一次,就在元素进入视口时,并避免在每个滚动事件上执行代码。
用户是否会调整浏览器窗口的大小?
大多数桌面用户会从最大化的浏览器窗口浏览网页,这可能是通用的,无论他们使用的是 Windows、Mac 还是 Linux;但这并不意味着我们可以忽略调整浏览器窗口大小的用户。
有时,用户会调整其 Windows 的大小,因此我们也必须考虑到这种情况,无论这种情况发生的几率有多大。
如果不这样做,则用户在调整窗口大小时可能会遇到重叠元素或者覆盖内容的元素的问题。
我们将无法获得用户的确切屏幕尺寸,因为即使用户最大化浏览器窗口,浏览器 UI 以及任务列(也称为系统托盘或者通知区域)也会占用一些空间。
窗口尺寸:
可以通过窗口对象的innerWidth 和innerHeight 属性访问窗口的尺寸;重要的是要注意,这只会为我们提供浏览器窗口的尺寸,而不是屏幕本身。
桌面设备允许调整浏览器窗口的大小,因此,窗口对象的尺寸不会与屏幕的尺寸相匹配。
但在大多数情况下,知道窗口的大小可能就足够了。
要获取当前窗口尺寸,我们可以这样做:
windowWidth = window.innerWidth; windowHeight = window.innerHeight; console.log(windowWidth + 'x' + windowHeight);
当人们想要检测屏幕宽度时,他们通常希望根据可用的屏幕空间对页面进行更改;在大多数情况下,为此目的使用 CSS 媒体查询会更好,但有时,仅使用 CSS 无法实现设计目标——这就是使用 JavaScript 的好地方。
上面的示例仅提供当前窗口尺寸,这对于检测第一页加载时的窗口尺寸很有用,但在用户调整浏览器窗口大小时则无效。
要在用户调整浏览器窗口大小时检测尺寸变化,我们必须设置一个事件侦听器;这可以通过 addEventListener 来完成,如下所示:
let showDimensions = document.querySelector("#show_dimensions"); window.addEventListener('resize', onWindowResize); function onWindowResize() { windowWidth = window.innerWidth; windowHeight = window.innerHeight; showDimensions.innerHTML = windowWidth + 'x' + windowHeight; }
这适用于所有现代浏览器。
这种方法的问题在于,当人们调整浏览器窗口大小时,脚本可能会导致延迟;为避免调整大小时出现延迟,我们可以通过添加 setTimeout 来减少脚本的干扰:
let showDimensions = document.querySelector("#show_dimensions"); let resizeTimer; window.addEventListener('resize', onWindowResize); function onWindowResize() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { windowWidth = window.innerWidth; windowHeight = window.innerHeight; showDimensions.innerHTML = windowWidth + 'x' + windowHeight; }, 100); }