searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

DOM 一些可能需要用到的api操作

2024-06-07 09:50:35
1
0
 DOM 一些可能需要用到的api操作

 

DOM元素的滚动方法
scrollIntoView
DOM的滚动
DOM规范中并没有规定各浏览器需要实现怎样的滚动页面区域,各浏览器实现了相应的方法,可以使用不同的方式控制页面区域的滚动。这些方法作为HTMLElement类型的扩展存在,所以它能在所有元素上使用。
 
1、scrollIntoView(alignWithTop)  滚动浏览器窗口或容器元素,以便在当前视窗的可见范围看见当前元素。如果alignWithTop为true,或者省略它,窗口会尽可能滚动到自身顶部与元素顶部平齐。-------目前各浏览器均支持
2、scrollIntoViewIfNeeded(alignCenter) 只在当前元素在视窗的可见范围内不可见的情况下,才滚动浏览器窗口或容器元素,最终让当前元素可见。如果当前元素在视窗中可见,这个方法不做任何处理。如果将可选参数alignCenter设置为true,则表示尽量将元素显示在视窗中部(垂直方向)------Safari、Chrome实现了这个方法
3、scrollByLines(lineCount) 将元素的内容滚动指定的行数的高度,lineCount的值可以为正值或是负值。---Safari、Chrome实现了这个方法
4、scrollByPages(pageCount) 将元素的内容滚动指定的页面的高度,具体高度由元素的高度决定。---Safari、Chrome实现了这个方法
scrollIntoView()和scrollIntoVIewIfNeeded()作用的是元素的窗口,而scrollByLines()、scrollByPages()影响元素自身,下面是几个示例:
 
**将页面主体滚动5行**
 
document.body.scrollByLines(5);
 
**确保当前元素可见**
 
document.getElementById(“test”).scrollIntoView();   //
 
true:对象的顶端与当前窗口的顶部对齐
false:对象的底端与当前窗口的顶部对齐
 
确保只在当前元素不可见的情况下才使其可见
 
document.getElementById(“test”).scrollIntoViewIfNeeded();
 
将页面主体往回滚1页
 
doument.body.scrollByPages(-1);
 
(以上内容摘自《JavaScript高级程序设计(第2版)》)
 
判断DOM元素是否可见
(1)判断一个元素是否在可视区域,我们有通常有两种办法,第一种是:使用元素的 getBoundingClientRect 属性的 top 值和页面的 clientHeight进行对比, 如果top的值小于 clientHeight表示元素在可视区域内,这种方式的缺点是需要监听scroll事件.
(2)第二种是利用高级特性 Intersection Observer 来判断元素是否可见,这种方式不用监听scroll事件,元素可见变调用回调,在回调里面处理。
回调Callback

 

Intersection Observer的翻译就是“交点观察”,因此,他的回调就成了重点。当观察元素与根元素之间的交叉状态发生变化时,它会将这部分信息反馈回来--通过回调告知

 

在回调函数里,我们会接受到两个对象,发生状态变化的元素集合以及监听者本身(注意:创建时,会将所有被观察元素的状态传递过来),监听者本身我们可以通过它增加或者减少监听的元素或者销毁自身(后续讲),这里我们更关注观察元素
function callback(entries,observer) {
  entries -> 一系列被观察的元素
  observer -> 观察者
}

 

entries 是一个 IntersectionObserverEntry 对象的数组,IntersectionObserverEntry 包换以下元素(来自MDN
    boundingClientRect: 返回包含目标元素的边界信息的DOMRectReadOnly. 边界的计算方式与 Element.getBoundingClientRect() 相同
    intersectionRatio: 返回intersectionRect 与 boundingClientRect 的比例值
    intersectionRect: 返回一个 DOMRectReadOnly 用来描述根和目标元素的相交区域
    isIntersecting: 返回一个布尔值, 如果目标元素与交叉区域观察者对象(intersection observer) 的根相交,则返回 true .如果返回 true, 则 IntersectionObserverEntry 描述了变换到交叉时的状态; 如果返回 false, 那么可以由此判断,变换是从交叉状态到非交叉状态
    rootBounds: 返回一个 DOMRectReadOnly 用来描述交叉区域观察者(intersection observer)中的根
    target: 与根出现相交区域改变的元素 (Element)
    time: 返回一个记录从 IntersectionObserver 的时间原点(time origin)到交叉被触发的时间的时间戳(DOMHighResTimeStamp)

 

具体的值是多少,我们可以在最上面的例子中看到,需要注意传递过来的对象都是只读(毕竟回调,只是通知你发生变化了)
参数options

 

我们可以通过 options 配置 IntersectionObserver,他包含以下几项配置

 

    root: 监听元素的祖先元素Element对象,其边界盒将被视作视口。目标在根的可见区域的的任何不可见部分都会被视为不可见。默认情况下文档视口会作为root
    rootMargin: 一个在计算交叉值时添加至根的边界盒(bounding_box)中的一组偏移量,类型为字符串(string) ,可以有效的缩小或扩大根的判定范围从而满足计算需要。语法大致和CSS 中的margin 属性等同。默认值是"0px 0px 0px 0px"。
    threshold: 规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组0.0到1.0之间的数组。若指定值为0.0,则意味着监听元素即使与根有1像素交叉,此元素也会被视为可见. 若指定值为1.0,则意味着整个元素都交叉时视为可见。阈值的默认值为0.0。

 

在上面的例子中,我未修改root与rootMargin,你可以将浏览器的窗口作为可见区域,threshold定义了一系列数组,意味着到达那些交叉比时触发回调
属性

 

在创建或者回调函数中,我们可以得到 IntersectionObserver 对象,他包含以下属性:

 

    root: 所监听对象的具体祖先元素(element)。如果未传入值或值为null,则默认使用顶级文档的视窗
    rootMargin: 计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要。此属性返回的值可能与调用构造函数时指定的值不同,因此可能需要更改该值,以匹配内部要求。所有的偏移量均可用像素(pixel)(px)或百分比(percentage)(%)来表达, 默认值为"0px 0px 0px 0px"
    thresholds: 一个包含阈值的列表, 按升序排列, 列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会生成一个通知(Notification)。如果构造器未传入值, 则默认值为0

 

IntersectionObserver 的属性也都是只读,他在创建之后不支持修改
方法

 

IntersectionObserver 通过以下方法添加或者取消监听元素

 

    IntersectionObserver.disconnect() 使IntersectionObserver对象停止监听工作。
    IntersectionObserver.observe() 使IntersectionObserver开始监听一个目标元素。
    IntersectionObserver.takeRecords() 返回所有观察目标的IntersectionObserverEntry对象数组。
    IntersectionObserver.unobserve() 使IntersectionObserver停止监听特定目标元素。
 
(以上内容摘自 Intersection Observer 简介 知乎专栏 zhuanlan.zhihu.com/p/96736098)

 

### 判断一个元素内部的元素是否被隐藏(可用于元素超出省略折叠)
这种时候通过完整高scrollHeight 和 显示高 height来比较判断,得出是否会出现省略号,当元素的scrollHeight > clientHeight 此时内部元素的高度大于父元素设置的高度,父元素overflow设置为hidden时子元素被隐藏。进而通过改变父元素高度height: auto或其他数值可以实现子元素的显示与隐藏

ResizeObserver
可用于监听元素的宽高变化,从而实现图表的伸缩,通常的做法是监听window 的resize事件,但是此事件只能监听浏览器视口的变化。父容器元素的大小变化无法监听

方法:

ResizeObserver.disconnect()

取消特定观察者目标上所有对 Element 的监听。

ResizeObserver.observe()

开始对指定 Element 的监听。

ResizeObserver.unobserve()

结束对指定 Element 的监听。


示例:

const h1Elem = document.querySelector("h1");
const pElem = document.querySelector("p");
const divElem = document.querySelector("body > div");
const slider = document.querySelector('input[type="range"]');
const checkbox = document.querySelector('input[type="checkbox"]');

divElem.style.width = "600px";

slider.addEventListener("input", () => {
  divElem.style.width = `${slider.value}px`;
});

const resizeObserver = new ResizeObserver((entries) => {
  for (const entry of entries) {
    if (entry.contentBoxSize) {
      // Firefox implements `contentBoxSize` as a single content rect, rather than an array
      const contentBoxSize = Array.isArray(entry.contentBoxSize)
        ? entry.contentBoxSize[0]
        : entry.contentBoxSize;

      h1Elem.style.fontSize = `${Math.max(
        1.5,
        contentBoxSize.inlineSize / 200,
      )}rem`;
      pElem.style.fontSize = `${Math.max(
        1,
        contentBoxSize.inlineSize / 600,
      )}rem`;
    } else {
      h1Elem.style.fontSize = `${Math.max(
        1.5,
        entry.contentRect.width / 200,
      )}rem`;
      pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
    }
  }

  console.log("Size changed");
});

resizeObserver.observe(divElem);

checkbox.addEventListener("change", () => {
  if (checkbox.checked) {
    resizeObserver.observe(divElem);
  } else {
    resizeObserver.unobserve(divElem);
  }
});
(示例内容摘自MDN)

0条评论
0 / 1000
王****斌
2文章数
0粉丝数
王****斌
2 文章 | 0 粉丝
王****斌
2文章数
0粉丝数
王****斌
2 文章 | 0 粉丝
原创

DOM 一些可能需要用到的api操作

2024-06-07 09:50:35
1
0
 DOM 一些可能需要用到的api操作

 

DOM元素的滚动方法
scrollIntoView
DOM的滚动
DOM规范中并没有规定各浏览器需要实现怎样的滚动页面区域,各浏览器实现了相应的方法,可以使用不同的方式控制页面区域的滚动。这些方法作为HTMLElement类型的扩展存在,所以它能在所有元素上使用。
 
1、scrollIntoView(alignWithTop)  滚动浏览器窗口或容器元素,以便在当前视窗的可见范围看见当前元素。如果alignWithTop为true,或者省略它,窗口会尽可能滚动到自身顶部与元素顶部平齐。-------目前各浏览器均支持
2、scrollIntoViewIfNeeded(alignCenter) 只在当前元素在视窗的可见范围内不可见的情况下,才滚动浏览器窗口或容器元素,最终让当前元素可见。如果当前元素在视窗中可见,这个方法不做任何处理。如果将可选参数alignCenter设置为true,则表示尽量将元素显示在视窗中部(垂直方向)------Safari、Chrome实现了这个方法
3、scrollByLines(lineCount) 将元素的内容滚动指定的行数的高度,lineCount的值可以为正值或是负值。---Safari、Chrome实现了这个方法
4、scrollByPages(pageCount) 将元素的内容滚动指定的页面的高度,具体高度由元素的高度决定。---Safari、Chrome实现了这个方法
scrollIntoView()和scrollIntoVIewIfNeeded()作用的是元素的窗口,而scrollByLines()、scrollByPages()影响元素自身,下面是几个示例:
 
**将页面主体滚动5行**
 
document.body.scrollByLines(5);
 
**确保当前元素可见**
 
document.getElementById(“test”).scrollIntoView();   //
 
true:对象的顶端与当前窗口的顶部对齐
false:对象的底端与当前窗口的顶部对齐
 
确保只在当前元素不可见的情况下才使其可见
 
document.getElementById(“test”).scrollIntoViewIfNeeded();
 
将页面主体往回滚1页
 
doument.body.scrollByPages(-1);
 
(以上内容摘自《JavaScript高级程序设计(第2版)》)
 
判断DOM元素是否可见
(1)判断一个元素是否在可视区域,我们有通常有两种办法,第一种是:使用元素的 getBoundingClientRect 属性的 top 值和页面的 clientHeight进行对比, 如果top的值小于 clientHeight表示元素在可视区域内,这种方式的缺点是需要监听scroll事件.
(2)第二种是利用高级特性 Intersection Observer 来判断元素是否可见,这种方式不用监听scroll事件,元素可见变调用回调,在回调里面处理。
回调Callback

 

Intersection Observer的翻译就是“交点观察”,因此,他的回调就成了重点。当观察元素与根元素之间的交叉状态发生变化时,它会将这部分信息反馈回来--通过回调告知

 

在回调函数里,我们会接受到两个对象,发生状态变化的元素集合以及监听者本身(注意:创建时,会将所有被观察元素的状态传递过来),监听者本身我们可以通过它增加或者减少监听的元素或者销毁自身(后续讲),这里我们更关注观察元素
function callback(entries,observer) {
  entries -> 一系列被观察的元素
  observer -> 观察者
}

 

entries 是一个 IntersectionObserverEntry 对象的数组,IntersectionObserverEntry 包换以下元素(来自MDN
    boundingClientRect: 返回包含目标元素的边界信息的DOMRectReadOnly. 边界的计算方式与 Element.getBoundingClientRect() 相同
    intersectionRatio: 返回intersectionRect 与 boundingClientRect 的比例值
    intersectionRect: 返回一个 DOMRectReadOnly 用来描述根和目标元素的相交区域
    isIntersecting: 返回一个布尔值, 如果目标元素与交叉区域观察者对象(intersection observer) 的根相交,则返回 true .如果返回 true, 则 IntersectionObserverEntry 描述了变换到交叉时的状态; 如果返回 false, 那么可以由此判断,变换是从交叉状态到非交叉状态
    rootBounds: 返回一个 DOMRectReadOnly 用来描述交叉区域观察者(intersection observer)中的根
    target: 与根出现相交区域改变的元素 (Element)
    time: 返回一个记录从 IntersectionObserver 的时间原点(time origin)到交叉被触发的时间的时间戳(DOMHighResTimeStamp)

 

具体的值是多少,我们可以在最上面的例子中看到,需要注意传递过来的对象都是只读(毕竟回调,只是通知你发生变化了)
参数options

 

我们可以通过 options 配置 IntersectionObserver,他包含以下几项配置

 

    root: 监听元素的祖先元素Element对象,其边界盒将被视作视口。目标在根的可见区域的的任何不可见部分都会被视为不可见。默认情况下文档视口会作为root
    rootMargin: 一个在计算交叉值时添加至根的边界盒(bounding_box)中的一组偏移量,类型为字符串(string) ,可以有效的缩小或扩大根的判定范围从而满足计算需要。语法大致和CSS 中的margin 属性等同。默认值是"0px 0px 0px 0px"。
    threshold: 规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组0.0到1.0之间的数组。若指定值为0.0,则意味着监听元素即使与根有1像素交叉,此元素也会被视为可见. 若指定值为1.0,则意味着整个元素都交叉时视为可见。阈值的默认值为0.0。

 

在上面的例子中,我未修改root与rootMargin,你可以将浏览器的窗口作为可见区域,threshold定义了一系列数组,意味着到达那些交叉比时触发回调
属性

 

在创建或者回调函数中,我们可以得到 IntersectionObserver 对象,他包含以下属性:

 

    root: 所监听对象的具体祖先元素(element)。如果未传入值或值为null,则默认使用顶级文档的视窗
    rootMargin: 计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要。此属性返回的值可能与调用构造函数时指定的值不同,因此可能需要更改该值,以匹配内部要求。所有的偏移量均可用像素(pixel)(px)或百分比(percentage)(%)来表达, 默认值为"0px 0px 0px 0px"
    thresholds: 一个包含阈值的列表, 按升序排列, 列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会生成一个通知(Notification)。如果构造器未传入值, 则默认值为0

 

IntersectionObserver 的属性也都是只读,他在创建之后不支持修改
方法

 

IntersectionObserver 通过以下方法添加或者取消监听元素

 

    IntersectionObserver.disconnect() 使IntersectionObserver对象停止监听工作。
    IntersectionObserver.observe() 使IntersectionObserver开始监听一个目标元素。
    IntersectionObserver.takeRecords() 返回所有观察目标的IntersectionObserverEntry对象数组。
    IntersectionObserver.unobserve() 使IntersectionObserver停止监听特定目标元素。
 
(以上内容摘自 Intersection Observer 简介 知乎专栏 zhuanlan.zhihu.com/p/96736098)

 

### 判断一个元素内部的元素是否被隐藏(可用于元素超出省略折叠)
这种时候通过完整高scrollHeight 和 显示高 height来比较判断,得出是否会出现省略号,当元素的scrollHeight > clientHeight 此时内部元素的高度大于父元素设置的高度,父元素overflow设置为hidden时子元素被隐藏。进而通过改变父元素高度height: auto或其他数值可以实现子元素的显示与隐藏

ResizeObserver
可用于监听元素的宽高变化,从而实现图表的伸缩,通常的做法是监听window 的resize事件,但是此事件只能监听浏览器视口的变化。父容器元素的大小变化无法监听

方法:

ResizeObserver.disconnect()

取消特定观察者目标上所有对 Element 的监听。

ResizeObserver.observe()

开始对指定 Element 的监听。

ResizeObserver.unobserve()

结束对指定 Element 的监听。


示例:

const h1Elem = document.querySelector("h1");
const pElem = document.querySelector("p");
const divElem = document.querySelector("body > div");
const slider = document.querySelector('input[type="range"]');
const checkbox = document.querySelector('input[type="checkbox"]');

divElem.style.width = "600px";

slider.addEventListener("input", () => {
  divElem.style.width = `${slider.value}px`;
});

const resizeObserver = new ResizeObserver((entries) => {
  for (const entry of entries) {
    if (entry.contentBoxSize) {
      // Firefox implements `contentBoxSize` as a single content rect, rather than an array
      const contentBoxSize = Array.isArray(entry.contentBoxSize)
        ? entry.contentBoxSize[0]
        : entry.contentBoxSize;

      h1Elem.style.fontSize = `${Math.max(
        1.5,
        contentBoxSize.inlineSize / 200,
      )}rem`;
      pElem.style.fontSize = `${Math.max(
        1,
        contentBoxSize.inlineSize / 600,
      )}rem`;
    } else {
      h1Elem.style.fontSize = `${Math.max(
        1.5,
        entry.contentRect.width / 200,
      )}rem`;
      pElem.style.fontSize = `${Math.max(1, entry.contentRect.width / 600)}rem`;
    }
  }

  console.log("Size changed");
});

resizeObserver.observe(divElem);

checkbox.addEventListener("change", () => {
  if (checkbox.checked) {
    resizeObserver.observe(divElem);
  } else {
    resizeObserver.unobserve(divElem);
  }
});
(示例内容摘自MDN)

文章来自个人专栏
前端开发FEX团队
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0