爬虫類の可視化ポイント選択構成ツールのマウスポイント選択要素の取得


前言
前の2章では、どのように開発するかを紹介しました.chromeプラグインと使用方法vueポップアップボックスを構築chromeプラグイン、この章はページ要素の選択機能を実現し、効果は下図のように、マウスを要素の上に置くと、要素がハイライトされます.
主な実現構想は、ページと同じ幅の高いマスクを作成し、マスクのマウス移動イベントを傍受し、elementFromPoint関数を使用して現在のマウスの位置のページ要素を取得し、具体的には以下のように実現する.shelter.jsこれは主関数である.
import $ from 'jquery';
import validateSelect from './validateSelected';
import isContentElement from "./isContentElement";

//    
export default class {
    constructor() {
        this.shelter = $("
"); // div this.shelter.attr("id", "__pAp_SpiderShelter"); this.block = $("
"); this.lastSelectEl = null; // this.shelterInterval = null; $(document.body).append(this.shelter); $(document.body).append(this.block); } beginSelect(onDomClick, onContextMenu, callback) { let that = this; this.shelter.css("position", "absolute"); this.shelter.css("display", "block"); this.shelter.addClass("pAp_spider_Selecter_Block"); this.shelter.bind("click", onDomClick); this.shelter.show(); this.shelter.css("width", "100%"); this.shelter.css("height", $(document).height() + "px"); this.shelter.css("left", "0"); this.shelter.css("top", "0"); this.shelter.mousemove(this.onShelterMouseMove(callback)); // function initCover() { that.shelterInterval = setInterval(function() { // , if ($(document).height() > that.shelter.height()) { that.hideCover(); that.showCover(); } }, 500); } // , this.shelter.mouseover(function() { if (that.shelterInterval) { clearInterval(that.shelterInterval); that.shelterInterval = null; } }).mouseout(initCover); this.block.css("position", "absolute"); this.block.css("display", "block"); this.block.show(); this.showShelter(); // this.block.css("z-index", "19891009") this.shelter.css("z-index", "19891010"); // document.oncontextmenu = onContextMenu; // , $(this.shelter).on("mousewheel", function(evt) { event.stopPropagation(); event.preventDefault(); var height = evt.originalEvent.wheelDelta; if (!that.lastSelectEl) return; var el = that.lastSelectEl.get(0); while (el) { if (el.scrollHeight > el.offsetHeight || el.tagName == "BODY") { var lastTop = el.scrollTop; el.scrollTop = el.scrollTop - height; if (lastTop !== el.scrollTop) { break; } } el = el.parentElement; } }); initCover(); }; endSelect(callback) { if (this.shelterInterval) { clearInterval(this.shelterInterval); this.shelterInterval = null; } this.shelter.unbind(); this.shelter.remove(); this.block.remove(); $(document).unbind(); document.oncontextmenu = function() {}; callback && callback(); }; showShelter() { this.block.css("box-shadow", "0 0 20px #d4930d"); }; hideShelter() { this.block.css("box-shadow", "none"); }; // onShelterMouseMove(callback) { let that = this; var position = { x: 0, y: 0 }; return function(e) { event.stopPropagation(); if (Math.abs(position.x - e.pageX) > 10 || Math.abs(position.y - e.pageY) > 10) { // that.hideCover(); // , var el = $(document.elementFromPoint(e.clientX, e.clientY)); // that.showCover(); // if (!isContentElement(el)) return; // , if (!validateSelect(el)) { el = el.parent(); } if (!that.lastSelectEl || that.lastSelectEl.get(0) != el.get(0)) { that.lastSelectEl = el; } position = { x: e.pageX, y: e.pageY }; that.setPosition(el, that.block); callback && callback(that.lastSelectEl); } } } setShelterPosition(el) { this.setPosition(el, this.shelter); } /** * * @param {Jquery Dom Element} el * @param {Jquery Dom Element} shelter */ setPosition(el, shelter) { if ((el.width() == 0 || el.height() == 0) && el.get(0).tagName == 'A' && el.children().length) { that.setPosition(el.children().eq(0), shelter); return; } var paddingObject = { left: parseInt(el.css("padding-left")), top: parseInt(el.css("padding-top")), right: parseInt(el.css("padding-right")), bottom: parseInt(el.css("padding-bottom")) }; var _width = 0, _height = 0; if (!isNaN(paddingObject.left)) { _width += paddingObject.left; } if (!isNaN(paddingObject.right)) { _width += paddingObject.right; } if (!isNaN(paddingObject.top)) { _height += paddingObject.top; } if (!isNaN(paddingObject.bottom)) { _height += paddingObject.bottom; } var top = parseInt(el.offset().top); var height = el.height() + _height; var availHeight = $(document).height() - top; height = height > availHeight ? availHeight : height; var obj = { "left": parseInt(el.offset().left) + "px", "top": top + "px", "width": el.width() + _width, "height": height }; shelter.css(obj); }; hideCover() { this.block.css("z-index", "-2") this.shelter.css("z-index", "-1"); this.shelter.css("display", "none"); this.block.css("display", "none"); }; showCover() { this.shelter.css("display", "block"); this.block.css("display", "block"); this.block.css("z-index", "19891009") this.shelter.css("z-index", "19891010"); var height = $(document).height(); this.shelter.css("width", "100%"); this.shelter.css("height", height + "px"); this.shelter.css("left", "0"); this.shelter.css("top", "0"); }; setBlockCss(key, value) { this.block.css(key, value); } setShelterCss(key, value) { this.shelter.css(key, value); } }

validateSelected.js确保所选择的元素是页面本身的元素

import $ from 'jquery';

/**
 *             ,            
 * @param {*} element 
 */
export default function(element) {
    var el = $(element);

    if (el.attr("__pAp_select")) {
        return false;
    }

    if (el.hasClass("__pAp_selectrow")) {
        return false;
    }
    return true;
};
isContentElement.jsこの関数の役割も、選択された要素がページ固有の要素であることを保証することです.
import $ from 'jquery';

/*
            ,                   
*/
export default function(element) {
    var expectClasses = [".layuiex", ".layuiex-layer", ".layuiex-layer-shade", ".layuiex-layer-moves", ".pAp_spider_Selecter_Block"];
    for (var _i = 0; _i < expectClasses.length; _i++) {
        var els = $(expectClasses[_i]);
        for (var a = 0; a < els.length; a++) {
            //$.contains( container, contained )
            //                
            //container    Element                    。
            //contained    Element                   。
            if ($.contains(els.eq(a).get(0), element) || els.eq(a).get(0) == element) {
                return false;
            }
        }
    }
    return true;
};

これでページ選択関数が書き終わり、次はmainで参照します.jsに関数を追加
import Vue from 'vue';
import $ from "jquery";
import './layer/layer.css';
import layer from './layer/layer';
import shelter from './js/selector/shelter';

Vue.config.productionTip = false;
let shelterUi = new shelter();

......

new Vue({
    el: "#__paApa_container",
    components: {},
    data() {
        return {
            selectedEl: null
        };
    },
    mounted() {
        let that = this;
        shelterUi.beginSelect(that.onDomClick, null,
            function(selectedEl) {
                that.selectedEl = selectedEl;
            });
    },
    methods: {
        onDomClick() {
            console.log('  ');
        }
    }
});

以上でページ選択機能が完了しました