zoukankan      html  css  js  c++  java
  • jquery逆向css selector path生成

    场景:

    一般情况我们都是已知css选择器的情况下,去操作dom元素,而在做爬虫时,为了方便的使用可视化的方式,让用户能够快速选区要采集的元素节点,需要在页面上点击某个元素后自动获取其selector。

    思路:

    从点击元素开始向上(父节点)遍历,若遍历过程中的某个选择器能够唯一确定这个元素,则返回。当遇到有id属性的元素时直接返回。

    实现:

    
    /**
     * 获取css path
     * @param callback
     * callback接收两个参数:元素的css路径,选择元素的jq对象
     */
    function getCssPath(callback) {
      let all = $('*');
      all.click(function () {
        let path = cssPath($(this));
        if ($(path).hasClass('_selected')) {
          $(path).removeClass('_selected');
        } else {
          $(path).addClass('_selected');
        }
        callback(path, $(this));
        return false;
      })
    }
    
    function cssPath(el) {
      let path = [];
      while (el && el[0].tagName !== 'HTML') {
        let selector = el[0].tagName.toLowerCase();
        if (el.attr('id')) {
          selector += '#' + el.attr('id');
          path.unshift(selector);
          break;
        } else {
          if (el.attr('class') && el.attr('class') !== '' && el.attr('class').trim() !== '_selected' && selector !== 'input') {
            let classStr = el.attr('class');
            let cl = '.' + classStr.trim().split(/s+/).join('.');
            if ($(selector + cl + '>' + (path.length > 0 ? path.join(" > ") : '')).length === 1) {
              path.unshift(selector + cl);
              break;
            }
            let suffixLen = el.nextAll();
            let nth = el.prevAll().length + 1;
            if (nth !== 1 || suffixLen !== 0)
              selector += ":nth-child(" + nth + ")";
          } else if (selector === 'input' && el.attr('name')) {
            if ($(selector + '[name=' + el.attr('name') + ']').length === 1) {
              path.unshift(selector + '[name=' + el.attr('name') + ']');
              break;
            }
          } else {
            let nth = el.prevAll().length + 1;
            if (nth !== 1)
              selector += ":nth-child(" + nth + ")";
          }
        }
        path.unshift(selector);
        el = el.parent();
      }
      return path.join(" > ");
    }
    

    其中_selected类如下:

    ._selected{
      background-color:green !important;
    }
    

    使用方式:

    $(document).ready(function () {
      setTimeout(function () {
        getCssPath(function (path, el) {
          alert($(path).text() + ':' + el.text())
        });
    
      }, 2000)
    });
    

    结果对比:

    浏览器copy selector生成的path:

    #app > div > div.app-frame.h-layout.h-layout-has-sider.h-layout-sider-fixed > div.h-layout.h-layout-header-fixed > div.h-layout-content > div.app-frame-content > div > div > div:nth-child(2) > div > div.h-panel-bar > div.h-panel-title._selected
    

    本代码生成的path:

    div.h-row > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1)
    

    相对于浏览器生成的来说,更简洁

  • 相关阅读:
    Web Control 开发系列(三) 解析IPostBackEventHandler和WebForm的事件机制
    Web Control 开发系列(一) 页面的生命周期
    异步导入滚动条
    前端复习之HTML5
    前端复习之jQuery大全
    前端复习之JavaScript(ECMAScript5)
    前端复习之DOM、BOM
    前端复习之Ajax,忘完了
    前端复习之css
    前端基础复习之HTML
  • 原文地址:https://www.cnblogs.com/cnsec/p/13286628.html
Copyright © 2011-2022 走看看