关于网页元素圈选

178 阅读2分钟

从前面我们已验证配置自动化是可行的,接下来就实现元素选择,当然有了配置化,我们也是可以通过浏览器F12的调试工具去把元素xpath复制出来(ps:反正又不是不能用),但是这不是我们最终目的。 其实圈选效果如下:(通过鼠标选择元素) 在这里插入图片描述

其实看上去效果如F12调试模式一样: 在这里插入图片描述 都是移动鼠标去选取元素的位置。

实现

有上图可以把圈选功能的实现拆分以下几个步骤, 1、 监听鼠标移动 2、获取鼠标移到的元素 3、获取元素的位置、大小、边距等 4、绘制一个选择遮罩层 5、计算xpath(配置元素时,需要) 只要把这几个步骤实现,那么一个简单的圈选功能就ok了。

步骤1

监听鼠标移动,

body.addEventListener('mousemove',  (e) => {
 //   圈选逻辑
 _onMove(e)
}, {
    capture: true,
    passive: true,
  });

步骤2


/** 获取 鼠标移动 圈选 目标节点元素  */
function getTouchMouseTargetElement(e) {
  if (e instanceof TouchEvent && e.touches) {
      const changedTouch = e.changedTouches[0];
      return document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
  }
  return e.target;
}

步骤3


/** 获取元素 内边距、外边距、宽高等元素数据 */
function getElementInfo(ele) {
  const result = {};
  const requiredValue = [
      'border-top-width',
      'border-right-width',
      'border-bottom-width',
      'border-left-width',
      'margin-top',
      'margin-right',
      'margin-bottom',
      'margin-left',
      'padding-top',
      'padding-right',
      'padding-bottom',
      'padding-left',
      'z-index',
  ];

  const computedStyle = getComputedStyle(ele);
  requiredValue.forEach((item) => {
      result[item] = parseFloat(computedStyle.getPropertyValue(item)) || 0;
  });

  const info = ele.getBoundingClientRect();

  // FIXME: 简单兼容svg元素offsetWidth, offsetHeight 为空的场景
  // TODO: 需要判断Svg元素的box-sizing,来决定其width,height是否需要减去padding, border
  const width =
      ele.offsetWidth === undefined
          ? info.width
          : ele.offsetWidth -
            result['border-left-width'] -
            result['border-right-width'] -
            result['padding-left'] -
            result['padding-right'];

  const height =
      ele.offsetHeight === undefined
          ? info.height
          : ele.offsetHeight -
            result['border-top-width'] -
            result['border-bottom-width'] -
            result['padding-top'] -
            result['padding-bottom'];

  mixin(result, {
      width,
      height,
  });
  mixin(result, findPos(ele));
  return result;
}

步骤4

绘制一个选择遮罩层。

/** 创建圈选蒙层 */
function addOverlay()  { .... }

步骤5

function getXpath(ele, allId = false) {....}

最后

这个就是实现基于js实现圈选元素的大概思路。有兴趣的可以查看源码,常规的圈选功能可以,接下来就可以放在谷歌插件的上了,完成谷歌插件圈选元素,并设置配置参数。嘿嘿。