• 通过MutationObserver监听DOM元素,做一个位置随指定元素位置变化而变化的气泡 | ResizeObserver监听元素大小


    -

    最近需要把时间轴修改成自己想要的样子,需要在时间轴的当前时间条上设置一个气泡,但是没有这个api,于是想到一个办法,通过监听 时间条dom元素,获取时间条的位置,然后创建一个元素当做气泡,这个气泡的位置会随着时间条的位置变化而变化;

    1、需要用到MutationObserver 来监听时间条dom元素,

    2、用DOM.getBoundingClientRect()方法监听dom相对于窗口的位置;

    3、根据时间条的位置,给创建的气泡元素设置位置,从而达到给时间条加气泡的效果;

    4、为了简化一些,我用了一个div当做时间条,设置一个定时器让它持续移动。可以模拟出来拖动时间条的场景。

    上代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>observer</title>
    <style>
    .wrap{
      width:400px;
      height:400px;
      position: relative;
      margin-left:200px;
    }
    .box{
      width: 300px;
      height:300px;
      position: absolute;
      top:0;
      left:0;
      background:cadetblue;
      clip-path: polygon(15px 0, calc(100% - 15px) 0, 100% 15px,  100% calc(100% - 15px), calc(100% - 15px) 100%, 15px 100%, 0 calc(100% - 15px), 0 15px)
    }
    .pop{
      position: fixed;
      border:1px solid black;
      border-radius:4px;
      padding: 4px;
      box-shadow: 0px 0px 4px 2px black inset;
      user-select: none;
    }
    </style>
    </head>
    <body>
    <div class="wrap">
      <div class="box"></div>
    </div>
    
    
    <script>
    let box = document.querySelector(".box");
    let add = 1;
    setInterval(() => {
      let left = parseInt(getComputedStyle(box).left);
      console.log(left);
      if(left > 300 ){
        add = -1;
      }
      if (left < 0){
        add = 1;
      }
      box.style.left = `${left + add}px`
    }, 1000);
    
    // 观察者的选项(要观察哪些突变)
    var config = { attributes: true, childList: false, subtree: false };// 只监听属性发生变化
     
     // 当观察到突变时执行的回调函数
     var callback = function(mutationsList) {
       console.log(mutationsList, 'mutationsList');
         mutationsList.forEach(function(item,index){
             if (item.type == 'childList') {
                console.log('有节点发生改变');
             } else if (item.type == 'attributes') {
                let targetleft = item.target.getBoundingClientRect().left;
                console.log(targetleft,'targetleft');
                let date = new Date();
                changePop(item.target, `
                  <div>${date.getYear()}年${date.getMonth() + 1}月${date.getDay()}</div>
                  <span>${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}</span>
                `)
             } else if (item.type == 'subtree') {
                console.log('subtree有变化');
             }
         });
     };
    
     // 创建一个链接到回调函数的观察者实例
     var observer = new MutationObserver(callback);
    
     // 开始观察已配置突变的目标节点
     observer.observe(box, config);
    
     // 停止观察
     //observer.disconnect();
    
    function changePop(parent,innerHTML){
      let pop = null;
      if(!document.querySelector('.pop')){
        pop = document.createElement('div');
        pop.classList.add('pop')
        document.body.appendChild(pop);
      } else {
        pop = document.querySelector('.pop');
      }
      let position = parent.getBoundingClientRect();
      pop.style.left = `${position.left}px`;
      pop.style.top = `${position.bottom}px`;
      pop.innerHTML = innerHTML;
    }
    </script>
    </body>
    </html>

    效果:气泡位置会跟着时间条的位置变化而变化

     下面简单说一下ResizeObserver API的使用,这个方法是监听元素的大小改变,不用通过window.resize来监听窗口改变来达到目的,有些时候只监听window.resize也是达不到目的的,因为我们可能用js来改变某一个元素的宽高,所以用ResizeObserver方法来监听会更加方便,不过这个API目前是实验阶段,在chrome浏览器已经支持

    文档地址:https://developer.mozilla.org/zh-CN/docs/Web/API/ResizeObserver

    <textarea id="main"></textarea>
    <script>
    
    
    // javascript
    
    let mainEl = document.querySelector('#main')
    const resizeObserver = new ResizeObserver(entries => {
      console.log(entries, 'entries');
      for (let entry of entries) {
        console.log(entry.contentRect, 'contentRect');
        entry.target.style.borderRadius = Math.max(0, 250 - entry.contentRect.width) + 'px';
      }
    });
    resizeObserver.observe(mainEl);
    
    // 取消某个元素监听
    //resizeObserver.unobserve(mainEl)
    
    // 取消全部元素监听
    //resizeObserver.disconnect()

     

     拖动富文本框,监听到实时的大小。

    -

  • 相关阅读:
    字符串比较
    LOOP AT SCREEN
    Trunc的日期用法
    【ABAP】SELECT-ENDSELECT尽量不要用
    【转】Abap For all entries in 使用
    01如何创建sequence:
    abap --MOVE-CORRESPONDING
    Abap 常用变量
    StringBuffer的用法
    Spring事务的传播方式
  • 原文地址:https://www.cnblogs.com/fqh123/p/15485444.html
Copyright © 2020-2023  润新知