关于获取被点击的页面元素路径 | 青训营笔记

174 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第28天

很多时候大家都需要获取页面的被点击的元素,一般我们会使用e.target来获取点击的位置,元素等信息并用于进一步的加工操作.但是有的时候我们不仅需要获取被点击的元素信息,还要获取它的父元素信息,那要怎么做呢?

其实事件e中包含了大量的信息,只是我们很少会用到其中的某些信息而已.我注意到事件e中的path属性就包含了事件点击元素的路径.

使用命令

console.log(e.path);

获取事件的路径,推荐在鼠标操作,键盘操作等情况下使用并事先测试该属性是否能正常使用.

输出的信息:

image.png

这里的信息为我自己写的网页上的内容.输出的信息为一个数组,以被点击的元素,其父元素依次排列.数组中的每一个元素均为对象,包含该节点的全部的信息

image.png

这里面大量的信息我就不做一一解读了,基本上可以满足绝大部分使用场景.

但是同时我们注意到,在数组中有body,html和document三个元素,很多时候我们还需要把这个路径数组进行处理才能得到我们想要的元素.一般我们使用id,class,localName,nodeName等元素标志信息对path数组进行筛选和处理.这里我编写了一段path的处理函数希望对大家有所帮助

另外我还根据处理好的路径编写一段寻路函数:

/**根据path获取domTree中的对应对象**/
export function getElement(path) {
  let i = 0;
  let j = 0;
  let temp = state.domTree;
  while (i < path.length) { //寻路算法,最后temp将等于目标父元素
    while (temp.child[j].id !== path[i].id) {
      // console.log(temp.child[j].id);
      // console.log(path[i].id);
      j++;
    }
    temp = temp.child[j];
    i++;
    j = 0;
  }
  return temp;
}

其运行在Vuex中,数据结构样例为:

const state = {
  /* 数据结构:
  树状,与dom树具有映射关系,存储各个元素的基本数据属性
  以下似乎是个例子?在正常情况下应只存在一个div元素盒子,没有下辖的a标签,
  目前存在改变后数据不能很好地抵达目标
  该数据结构并未正式投入使用*/
  domTree:
    {
      id: 'canvas',
      el: '<div>',
      style: {height: 560, width: 640}, //本大小为默认的试做大小,适配了Woceda的显示器,需要可更改
      events: [],
      text: '',
      child: [
        {
          id: 'div',
          el: '<bp-div/>',  //???
          style: {height: '200px', width: '200px',color: '#123456',backgroundColor:'',fontFamily:'',fontSize:''}, //样式
          events: [], // 绑定的事件?
          text: '我是一个div盒子', // 内容
          class: [], //目前只是用于存储
          child: [{ //子组件,可以有多个,为对象数组
            id: '114514',
            el: '<bp-link/>',
            style: {color: '#ccc',backgroundColor:'',fontFamily:'宋体',fontSize:''},
            events: [],
            href: '',
            text: '我应当是一个a标签',
            child: [],
          },
          ]
        },
      ]
    },
  pathBuffer:[],  //用来暂存需用控制的组件的路径信息
  elementBuffer:null,
}

这其实是我使用的虚拟dom,厉害的朋友可以尝试舍弃自己的虚拟dom,用商盟的寻路函数直接寻找Vue提供的VNode节点进行更改.

好了今天的分享就到这里.