VUE制作谷歌浏览器多类型截屏、抓取信息的插件

提到VUE大家都很熟悉,VUE可以做很多东西,包括SPA单页面应用,WEBAPP应用,小程序应用等等,但是你们有没有考虑过过,使用VUE来制作一款抓取网页数据(文字+截屏)的扩展呢?敢想就要敢做,Let's Go !

1. 开发目标:完成一款在POPUP窗口登陆后,在当前网页加载出一个可以获取网页文字信息,以及可以多类型截图的工具,截完图可以下载,最终操作完成后可以直接提交

2. 开发工具:vue、jquery、chrome extension api 、es6 、bootstrap

3. 具体功能:

(1)信息抓取:标题、副标题、内容

(2)截屏:当前窗口截屏、当前整个网页截屏、自定义区域截屏4. 

扫描二维码关注公众号,回复: 3354514 查看本文章

4. 最终效果预览:


 

5. 代码架构逻辑:

(1)页面层:content-script注入当前页面,生成功能框,监听鼠标事件,筛选文字信息,动态改变数据,通过vue动态渲染dom,在发出截屏信息后获取backgroud层发送过来的图片信息

(2)背景层:监听message信息,根据传递过来的值类型,进行多类型截屏,然后将图片数据返回给页面层

6. content-script.js 页面代码逻辑:

(1)抓取页面文字信息

getAllTags(){
    var elems = $('#plugin-body').get(0).getElementsByTagName('*');
    $('a').removeAttr("href");

    for(var i=0;i<elems.length;i++){

        elems[i].addEventListener('mousedown',(e)=>{
            if(this.focusInputIndex)
                this.inputData[this.focusInputIndex] = e.target.innerText;
            e.stopPropagation();
            e.cancelBubble = true;
        })

        elems[i].addEventListener('mouseup',(e)=>{
            this.cancelText();
            e.stopPropagation();
            e.cancelBubble = true;
        })

        elems[i].index = i;
        elems[i].onmouseover = function(e){
            
            // 插件边框
            for(var j=0;j<elems.length;j++){
                if(elems[j] == this){
                    continue;
                }
                elems[j].classList.remove('pluginRedBorder');
            }
            
            // 添加样式
            this.classList.add('pluginRedBorder');
            e.stopPropagation();
            e.cancelBubble = true;
        };
    }
}

(2)窗口截屏核心代码:

//content-script.js 发出截屏通知

windowCapture(){
  this.isShow = false;
  setTimeout(()=>{
    chrome.runtime.sendMessage({event:'windowCapture',value:''},(data)=>{
       this.defaultImage = data;
       this.isShow = true;
    });
  },200);
}

//background.js 收到通知并且做出截屏操作

chrome.tabs.captureVisibleTab({ format: 'png', quality: 100},(dataUrl)=>{
   callback(dataUrl);
});

(3)当前网页全屏截图

//content-script.js 发出全网页截图通知,切传递过去当前的网页信息

webCapture(){
  this.isShow = false;

  var pageSize = {
      scrollHeight: document.body.scrollHeight,
      scrollWidth: document.body.scrollWidth,
      clientWidth: document.documentElement.clientWidth,
      clientHeight: document.documentElement.clientHeight
  };

  //接收移动页面通知
  chrome.runtime.onMessage.addListener(function(message, sender, resCallback){
    switch(message.event){
      case 'scrollBy':
        window.scrollBy(message.value.x,message.value.y);
        break;
      case 'scrollTo':
        window.scrollTo(message.value.x,message.value.y);
      default:
        break;
    }
    resCallback({status:true});
  })

  //发送捕获
  setTimeout(()=>{
    chrome.runtime.sendMessage({event:'webCapture',value:pageSize},(data)=>{
      this.defaultImage = data;
      var image = new Image();
      image.src = data;
      image.onload = function(){
        $('body').append(this);
      }
      this.isShow = true;
    });
  },200);
}


// background.js 收到通知后分步骤全网页截图

new WebCapture(request.value,callback);

/* 全页面捕捉 */

function WebCapture(v,callback){
   
    this.currentY = 0;
    this.canvas = document.createElement('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.sw = v.scrollWidth;
    this.sh = v.scrollHeight;
    this.cw = v.clientWidth;
    this.ch = v.clientHeight;
    this.tabId = 0;
    this.screenData = '';
    this.captureImgData = '';
    this.callback = callback;

    //初始化相关函数
    this.init();
}

WebCapture.prototype = {
    constructor: WebCapture,
    //初始化方法
    init(){
        //1. 初始化获取tabId
        this.getTabId();
        //2. 获取当前tab页面的宽高且初始化canvas的宽高
        this.initWH();
    },
    //获取tabId
    getTabId(){
        chrome.tabs.getSelected((tab)=>{
            this.tabId = tab.id;
            //3. 初始化页面位置移动到顶部
            this.initPagePosition();
        })
    },
    //初始化canvas的宽高
    initWH(){
        this.canvas.width = this.sw;
        this.canvas.height = this.sh;
    },
    //初始化页面位置移动到顶部
    initPagePosition(){
        this.scrollPage('scrollTo',0,0);
    },
    //向Tab页面发出跳转通知
    scrollPage(event,x,y){
        chrome.tabs.sendMessage(this.tabId,{event,value:{x,y}},(res)=>{
            if(res.status){
                //执行绘制
                setTimeout(()=>{
                    this.captureWebPage();
                },1000);
            }
        })
    },
    //将当前窗口内容转换成 image Data
    captureWebPage(){
        chrome.tabs.captureVisibleTab((data)=>{
            this.screenData = data;
            //分阶段绘制canvas
            this.drawImage();
        })
    },
    //往Canvas中填充图片
    drawImage(){
        let img = new Image();
        img.src = this.screenData;

        img.onload = ()=>{
            //绘制到最底部
            if(this.currentY + this.ch >= this.sh){
                let lastHeight = this.ch - this.sh % this.ch;
                let y = 0;
                if(this.currentY == 0){
                    y = 0;
                }else{
                    y = this.currentY - lastHeight;
                }
                this.ctx.drawImage(img,0,0,this.cw,this.ch,0,y,this.cw,this.ch);
                this.getImage();
            }else{ //还没有绘制到最底部
                this.ctx.drawImage(img,0,0,this.cw,this.ch,0,this.currentY,this.cw,this.ch);
                this.currentY += this.ch;
                this.scrollPage('scrollBy',0,this.currentY);
            }   
        };
        
    },
    //获取到最终的图片
    getImage(){
        this.captureImgData = this.canvas.toDataURL('image/png');
        this.callback(this.captureImgData);
    }
}


(4)自定义区域拖拽截屏

//content-script.js 发出自定义区域截屏通知,切传递过去当前的网页信息

//区域截屏
areaCapture(){
  var that = this;
  this.isShow = false;
  var pageSize = {
      clientWidth: document.documentElement.clientWidth,
      clientHeight: document.documentElement.clientHeight,
      x:0,
      y:0,
      width:0,
      height:0
  };
  var xmlns = 'http://www.w3.org/2000/svg';
  var dom = document.createElementNS(xmlns,'svg');
  var rect = document.createElementNS(xmlns,'rect');
  
  dom.setAttribute('class','captureScreenBox');
  dom.setAttribute('width',pageSize.clientWidth);
  dom.setAttribute('height',pageSize.clientHeight);
  dom.setAttribute('viewBox',`0 0 ${pageSize.clientWidth} ${pageSize.clientHeight}`);
  dom.setAttribute('xmlns',xmlns);
  $(dom).append(rect);

  //点击拖拽自定义选区
  $(dom).on('mousedown',(e)=>{
    var x1 = e.clientX;
    var y1 = e.clientY;
    var x2 = 0;
    var y2 = 0;
    rect.setAttribute('x',x1);
    rect.setAttribute('y',y1);
    

    $(dom).on('mousemove',(e)=>{
      x2 = e.clientX;
      y2 = e.clientY;
      rect.setAttribute('width',Math.abs(x1-x2));
      rect.setAttribute('height',Math.abs(y1-y2));
      pageSize = Object.assign({},pageSize,{x:x1,y:y1,width:Math.abs(x1-x2),height:Math.abs(y1-y2)})
    });

    $(dom).on('mouseup',(e)=>{
      sendMessage();
      $(dom).hide();
      $(dom).off();
    })
  });


  //发出生成图片的通知
  function sendMessage(){
    chrome.runtime.sendMessage({event:'areaCapture',value:pageSize},(data)=>{
      that.defaultImage = data;
      var image = new Image();
      image.src = data;
      image.onload = function(){
        $('body').append(this);
      }
      that.isShow = true;
    });
  }

  $('body').append(dom);   
}

// background.js 收到通知后进行自定义区域截屏

new AreaCapture(request.value,callback);

function AreaCapture(v,callback){
   
    this.canvas = document.createElement('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.cw = v.clientWidth;
    this.ch = v.clientHeight;
    this.vw = v.width;
    this.vh = v.height;
    this.offsetX = v.x;
    this.offsetY = v.y; 
    this.tabId = 0;
    this.screenData = '';
    this.captureImgData = '';
    this.callback = callback;

    //初始化相关函数
    this.init();
}

AreaCapture.prototype = {
    constructor: AreaCapture,
    //初始化方法
    init(){
        //1. 初始化获取tabId
        this.getTabId();
        //2. 获取当前tab页面的宽高且初始化canvas的宽高
        this.initWH();
    },
    //获取tabId
    getTabId(){
        chrome.tabs.getSelected((tab)=>{
            this.tabId = tab.id;
            this.captureWebPage();
        })
    },
    //初始化canvas的宽高
    initWH(){
        this.canvas.width = this.vw;
        this.canvas.height = this.vh;
    },
    //将当前窗口内容转换成 image Data
    captureWebPage(){
        chrome.tabs.captureVisibleTab((data)=>{
            this.screenData = data;
            //分阶段绘制canvas
            this.drawImage();
        })
    },
    //往Canvas中填充图片
    drawImage(){
        let img = new Image();
        img.src = this.screenData;

        img.onload = ()=>{
            this.ctx.drawImage(img,this.offsetX,this.offsetY,this.vw,this.vh,0,0,this.vw,this.vh);
            this.getImage();
        };
        
    },
    //获取到最终的图片
    getImage(){
        this.captureImgData = this.canvas.toDataURL('image/png');
        this.callback(this.captureImgData);
    }
}

7. manifest.json核心配置:

{
  "name": "抓取网页内容、对网页进行多类型截屏",
  "description": "",
  "version": "1.0",
  "permissions": [
    "activeTab",
    "*://*/*",
    "unlimitedStorage",
    "storage",
    "pageCapture",
    "tabs",
    "<all_urls>"
  ],
  "background": {
     "scripts": ["scripts/background.js"],
     "persistent": false
  },
  "content_scripts": [
    {
      "matches": ["*://*.baidu.com/*"], 
      "js": ["scripts/vue.js","scripts/jquery.js","scripts/content-script.js"],
      "css" : ["css/bootstrap.min.css"]
    }
  ],
  "browser_action": {
      "default_title": "Set this page's color.",
      "default_icon": "icon.png",
      "default_popup": "popup.html"
  },
  "manifest_version": 2
}

8. 扩展文件目录:

  |— catch_web_page_content

     |— css

        |— bootstrap.min.css

     |— images

     |— scripts

        |— background.js

        |— content-script.js

        |— jquery.js

        |— popup.js

        |— vue.js

     |— icon.png

     |— manifest.json

     |— popup.html

7. github地址:

   GITHUB源代码直通车 >>

猜你喜欢

转载自blog.csdn.net/WU5229485/article/details/82711666