2025.12.6本周知识要点

34 阅读3分钟

1.ResizeObserver

监听element边界、尺寸变化

observer(el) {
  const cd = (entries) => {
    console.log('监控对象尺寸变化:', entries)
  }
  const observer = new ResizeObserver(cd);
  observer.observe(el);
  this.observeCfg = observer;
}

2.transform translateX()

更改元素位置,且不会导致reflow,性能好,优于直接设置left/right/margin

transform: translateX(42px);

3.element.getBoundingClientRect()

返回一个对象,包含元素大小和相对于视窗的位置

const elementRect = elem.getBoundingClientRect(element);
// elementRect拥有属性
elementRect.x    // 元素到视窗左侧距离
elementRect.y    // 元素到视窗右侧距离
elementRect.width // 元素宽度
elementRect.height // 元素高度
elementRect.top  // 元素到视窗上侧距离
elementRect.right // 元素到视窗右侧距离
elementRect.bottom // 元素到视窗下侧距离
elementRect.left // 元素到视窗左侧距离

image.png

4.element.offsetWidth/element.offsetHeight等

element.offsetWidth // 元素自身可视宽度加上左右 border 的宽度
element.offsetHeight // 元素自身可视高度加上上下 border 的宽度
element.offsetLeft // 元素自己 border 左边距离父元素 border 左边或者 body 元素 border 左边的距离
element.offsetTop // 元素自己 border 顶部距离父元素顶部或者 body 元素 border 顶部的距离
element.style     // 获取/设置元素的 style 属性

5.transition: all 0.2s ease

为元素的一个或多个样式的变化设置过渡效果

transition: all 0.2s ease // 所有样式变化 0.2s过渡效果,ease是先快后慢
transition: margin-left 0.2s linear // margin-left变化时0.2s过渡效果,linear是线性变化

6.background: linear-gradient()

设置背景色渐变

background: linear-gradient(to right, black, black 30%, white 30%, white 100%); // 设置背景色从左向右线性变化,black 30%代表30%的位置是黑色,根据节点渐进变化颜色

7.element.scrollIntoView

滚动元素的祖先容器,使得被调用该方法的元素对用户可见(即页面滚动到元素位置)

element.scrollIntoView({
    behavior: 'smooth', // 定义滚动是立即的(instant)还是平滑的(mooth)动画
    inline: 'nearest', // 定义元素在可滚动祖先容器内的水平对齐方式,start/center/end/nearest
    block: 'start' // 定义元素在可滚动祖先容器内的垂直对齐方式,start/center/end/nearest
})

8.文字最多三行,超过后加展开按钮

这里使用vue写的

<template>
  <div class="box-wrapper">
    <div ref="textBox" class="box" :class="{ 'ellipsis-box': folded }">
      <span class="folded-btn" @click="folded = !folded" v-if="isOver">
        <span v-if="folded">展开<i class="el-icon-arrow-down"></i></span>
        <span v-else>收起<i class="el-icon-arrow-up"></i></span>
      </span>
      <span ref="spanBox" class="text">{{ text }}</span>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    text: {
      default: '',
      type: String
    },
  },
  data() {
    return {
      isOver: false, // 文本是否超出三行,默认否
      folded: true, // 文本是否收起状态,默认收起
    }
  },
  mounted() {
    this.isOver = this.$refs.spanBox.offsetHeight > this.$refs.textBox.offsetHeight
  }
}
</script>

<style lang="scss" scoped>
.box-wrapper {
  display: flex;
}
.box {
  position: relative;
  &::before {
    content: '';
    float: right;
    width: 0;
    height: calc(100% - 20px);
  }
}
.ellipsis-box {
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-line-clamp: 3;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}
.text {
  font-family: PingFangSC, PingFang SC;
  font-weight: 400;
  font-size: 12px;
  color: var(--agent-text5-color);;
  line-height: 20px;
  text-align: left;
  font-style: normal;
}
.folded-btn {
  font-weight: 500;
  font-size: 12px;
  line-height: 20px;
  color: #DC573C;

  float: right;
  clear: both;
}
</style>

9.随鼠标移动的tooltip

// 挂载tooltip到body
mountTooltip() {
  const tooltipDiv = document.createElement('div');
  tooltipDiv.id = 'progress-chapter-tooltip';
  tooltipDiv.style = `
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    min-width: 10px;
    border-radius: 4px;
    box-shadow: 0px 4px 20px 0px rgba(0,0,0,0.2);
    transition: all 0.05s ease;
  `
  document.body.appendChild(tooltipDiv);
},
// 展示tooltip
showTooltip(text) {
  const tooltipDiv = document.getElementById('progress-chapter-tooltip');
  if (tooltipDiv) {
    tooltipDiv.style.opacity = 1;
    tooltipDiv.innerHTML = text
  }
},
// 隐藏tooltip
hideTooltip() {
  const tooltipDiv = document.getElementById('progress-chapter-tooltip');
  if (tooltipDiv) {
    tooltipDiv.style.opacity = 0;
  }
},
// 鼠标移入展示区域时,调用展示函数showTooltip,这里用了节流控制触发频率
handleMouseMEWithTooltip: throttle(
  function(type, e) {
    const tooltip = document.getElementById('progress-chapter-tooltip');
    const progressBar = this.$refs.progressBar.getBoundingClientRect();
    const body = document.body.getBoundingClientRect();
    // 微前端框架中,微应用的body到窗口的边缘有一段距离,需要减掉
    // transform: translateX()仅改变元素位置不触发重排,性能好
    tooltip.style.transform = `translateX(${e.pageX - tooltip.offsetWidth / 2 - body.left}px)`;
    tooltip.style.top = progressBar.bottom - body.top + 7 + 'px';
    tooltip.style.transitionProperty = type === 'enter' ? 'none' : 'all';
    this.showTooltip('tooltip展示文字');
  },
  50,
  {leading: true, trailing: false} // trailing设置false,延迟时间结束后不再触发,防止opacity再次设置为1导致tooltip不隐藏
),

10.js中event对象的offsetX、 clientX、pageX、screenX、 layerX、x之间的区别

developer.aliyun.com/article/637…

11.title属性:鼠标悬停后展示内容

image.png

12.vue中vm.$watch()

可以同时监听多个变量

// 键路径  
vm.$watch('a.b.c', function (newVal, oldVal) {  
    // 做点什么  
})
vm.$watch(  
    function () {  
        // 表达式 `this.a + this.b` 每次得出一个不同的结果时  
        // 处理函数都会被调用。  
        // 这就像监听一个未被定义的计算属性  
        return this.a + this.b  
    },  
    function (newVal, oldVal) {  
        // 做点什么  
    }  
)
// vm.$watch 返回一个取消观察函数,用来停止触发回调:
var unwatch = vm.$watch('a', cb)  
// 之后取消观察  
unwatch()