常见css问题

本文介绍了如何通过offsetTop、scrollTop、getBoundingClientRect和IntersectionObserver判断元素是否在可视区域,以及四种修改第三方UI组件库样式的技巧,包括添加class或style、使用深度选择器和冒号的区别。
摘要由CSDN通过智能技术生成

一、如何判断一个元素是否在可视区域中?

常用的是以下三种:

  • offsetTop、scrollTop

  • getBoundingClientRect

  • Intersection Observer

1、offsetTop、scrollTop、clientHeight

offectTop:元素的上外边框至包含元素的上内边框之间的像素距离

el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
1
代码实现:

function isInViewPortOfOne (el) {
    // viewPortHeight 兼容所有浏览器写法
    const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 
    const offsetTop = el.offsetTop
    const scrollTop = document.documentElement.scrollTop
    const top = offsetTop - scrollTop
    return top <= viewPortHeight
}

延伸知识点:

clientWidthclientHeight

  • clientWidth:元素内容区宽度加上左右内边距宽度,即clientWidth = content + padding
  • clientHeight:元素内容区高度加上上下内边距高度,即clientHeight = content + padding

scrollWidthscrolltHeight

  • scrollWidth:左右内边距宽度+元素内容的实际大小,即scrollWidth = content实际大小 + padding
  • scrollHeight:上下内边距高度+元素内容的实际大小,即scrollHeight = content实际大小 + padding

2、getBoundingClientRect

返回值是一个 DOMRect对象,拥有left, top, right, bottom, x, y, width, 和 height属性,

如果一个元素在视窗之内的话,那么它一定满足下面四个条件:

  • top 大于等于 0
  • left 大于等于 0
  • bottom 小于等于视窗高度
  • right 小于等于视窗宽度
function isInViewPort(element) {
  const viewWidth = window.innerWidth || document.documentElement.clientWidth;
  const viewHeight = window.innerHeight || document.documentElement.clientHeight;
  const {
    top,
    right,
    bottom,
    left,
  } = element.getBoundingClientRect();

  return (
    top >= 0 &&
    left >= 0 &&
    right <= viewWidth &&
    bottom <= viewHeight
  );
}

3、Intersection Observer(重叠观察者)

I用于判断两个元素是否重叠,因为不用进行事件的监听,性能方面相比getBoundingClientRect会好很多

使用步骤主要分为两步:创建观察者和传入被观察者

const options = {
  // 表示重叠面积占被观察者的比例,从 0 - 1 取值,
  // 1 表示完全被包含
  threshold: 1.0, 
  root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素
};

const callback = function(entries, observer) { 
    entries.forEach(entry => {
        entry.time;               // 触发的时间
        entry.rootBounds;         // 根元素的位置矩形,这种情况下为视窗位置
        entry.boundingClientRect; // 被观察者的位置举行
        entry.intersectionRect;   // 重叠区域的位置矩形
        entry.intersectionRatio;  // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算)
        entry.target;             // 被观察者
    });
};

// 1、创建观察者
const observer = new IntersectionObserver(callback, options);

// 2、传入被观察者
const target = document.querySelector('.target');
observer.observe(target);

二、如何修改第三方UI组件库样式

常用四种方法:

1、添加 class/style

<el-button type="success" class="mybutton" style="height: 250px;">按钮</el-button>
​
​
<style lang="css" scoped>
​
.mybutton{
    border-radius: 20px;
}
    
</style>

如果某个属性覆盖不了,就加属性的权重;

2、去除style标签上的scoped属性

为了避免样式污染,可以在需要修改的UI组件的外层添加自定义class等,向下包含UI组件的样式代码,这样可以防止影响到别的组件。

3、使用深度选择器

  • /deep/   sass和less的样式穿透
  •  >>>      stylus的样式穿透
  • ::v-deep  vue3中可以会出现/deep/编译报错,可以使用::v-deep。

使用:

// 1、/deep/是需要写在UI框架的样式类之前的
.liForm {
	/deep/.el-textarea {
		.el-input__count {
			bottom: 2px!important;
		}
	}
}
 
// 下面的方式不会生效**********
/deep/.liForm {
	.el-textarea {
		.el-input__count {
			bottom: 2px!important;
		}
	}	
}

// 2、>>>
<style scoped>
.a >>> .b { /* ... */ }
</style>

4、去除scoped+深度选择器

三、单冒号、双冒号区别

1、单冒号:伪类

伪类用于定义元素的特殊状态

常见伪类::hover  :active :focus

2、双冒号:伪元素

伪元素用于给某个元素的之前或之后插入特定内容的关键词

常见伪元素:::after  ::before

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值