自制一款可搜索图片、设置页面背景的浏览器插件

前几天一直在忙广东省厅的一个项目,几乎抽不出时间来写一些东西。终于到了周末,这两天花了点时间浏览了下谷歌扩展官网的api,发现有挺多很好玩的东西,且是在普通的web上玩不转的东西,然后就打算做一个可以直接搜索到图片且能直接点击设置当前页面背景的插件(扩展):

1.插件内百度图片搜索预览效果:

2. 该扩展的功能:直接点击顶部插件小按钮,弹出popup框,直接在框内搜索想要搜到的图片名称,点击(回车)瀑布流展示加载图片,往下拉到底部会异步加载新的图片,点击图片设置当前tab页面的背景图片。

3. 实现核心过程:

(1)popup层发出message消息通知

(2)background层监听message消息通知,通过switch筛选处理各种类型的消息通知

(3)根据backround层可以直接跨域的特征配置参数请求百度图片接口,获取数据 (注意异步特征:return true)

(4)通过回调传递到popup层发送message的回调函数中

(5)更新dom以及点击事件,点击每个item,通过chrome.tabs对应的设置对应页面的背景图片(功能复杂的条件下可以参考使用content-script来实现)

4. 核心manifest.json的配置文件内容:

{

  "name": "点击百度图片更换当前页面的背景图片",

  "description": "",

  "version": "1.0",

  "permissions": [

    "activeTab",

    "http://www.blogger.com/",

    "*://*/*",

    "unlimitedStorage"

  ],

  "background": {

     "scripts": ["scripts/background.js"],

     "persistent": false

  },

  "browser_action": {

      "default_title": "Set this page's color.",

      "default_icon": "icon.png",

      "default_popup": "popup.html"

  },

  "manifest_version": 2

}

5. popup层页面结构与交互实现:

(1)瀑布流页面结构:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Set Page Color Popup</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"" />
    <style>
    body {
      overflow: hidden;
      margin: 0px;
      padding: 0px;
      background: white;
    }
    .wrapper{ width:500px;height:auto; background-color:white;display:flex;flex-wrap: wrap;justify-content: space-around;align-content: flex-start;padding-bottom: 20px;}
    .wrapper:hover{  background-color:white ;  }
    .wrapper .box{ width:90px;height:50px;  margin-top:10px}
    .wrapper .box img{ width:100%; height:100%; }
    .formBox{ width:90%;margin:0 auto; margin-top:20px;}

    .content-wrap{ list-style: none;width:100%;height:auto;position: relative;top:0;left:0; padding-left: 0; column-count: 4; column-gap: 0;}
    .img-container{ width:96%;margin:0 auto; height:400px;padding:0;overflow-y: auto;}
    .cw-box{width:100%;height:auto;break-inside: avoid; box-sizing: border-box; padding: 5px;transform: scale(.9);cursor: pointer;transition:.3s ease;}
    .cw-box:hover{transform:scale(1);border:1px solid #ddd;}
    .cw-box img{width:100%;height:100%;}  

    .img-container::-webkit-scrollbar{ width:6px;height:100%;background:#eee;border:none;border-radius:3px;}
    .img-container::-webkit-scrollbar-thumb{ background:#ddd;border-radius:3px;  } 

    .wrapper .panel-title{  text-align:left; width:100%; text-indent: 23px; font-size: 13px;}
    </style>
    <script src="scripts/jquery.js"></script>
    <script src="scripts/popup.js"></script>
  </head>
  <body>

    <div class="wrapper" id="wrapper">

      <!-- 表单输入框 -->
      <div class="formBox">
        <div class="form-group">
          <div class="row">
            <div class="col-xs-10"> 
              <input type="text" class="form-control" id="searchContent" 
               placeholder="请输入搜索内容" value="林允儿" />
             </div>
            <div class="col-xs-2">
                <button type="button" class="btn btn-success searchBtn">搜索</button>
            </div>      
         </div>
        </div>
      </div>

     
     <span class="panel-title">
       搜索结果:
     </span>

      <!-- 图片吗展示内容 -->
      <div class="container img-container">
        <ul class="content-wrap">
          <!-- <li class="cw-box">
            <img src="images/1.jpg" class="cw-box-img" />
          </li> -->
        </ul>
      </div>

    </div>

  </body>
</html>

(2)逻辑交互popup.js :

// Popup类
class Popup{

  //构造函数  
  constructor(){
    this.loadOnoff = true;
    this.loadIndex = 1;
    this.str = '';
    this.init();
  }

  //初始化函数
  init(){
    //初始化事件
    this.initEvent();
  }

  //初始化事件
  initEvent(){
    var that = this;
    
    //绑定事件
    $(document).ready(function(){
      
      //回车
      $('#searchContent').keydown(function(e){
        switch(e.keyCode){
            case 13 : 
                $('.content-wrap').html('');
                that.sendEvent('getImage',$('#searchContent').val());
                break;
            default:
                break;
        }
      })  

      //点击设置背景图片
      $('.searchBtn').click(function(){
        $('.content-wrap').html('');
        that.sendEvent('getImage',$('#searchContent').val());
      });
      
      //监听滚动
      $('.img-container').scroll(function(e){
        var maxHeight = $('.content-wrap').height() - $(this).height();
        if(Math.abs(this.scrollTop - maxHeight) < 30){
            console.log(that.loadOnoff);
            if(that.loadOnoff){
                that.loadIndex++;
                that.sendEvent('getImage',$('#searchContent').val())
                that.loadOnoff = false;
            }
        }
      });

    });

  }

  //发送消息通知
  sendEvent(event,message){
    chrome.runtime.sendMessage({event: event, value: message, loadIndex: this.loadIndex},(response)=>{
      this.showDomImage(response.data);
    });
  }

  //设置DOM显示
  showDomImage(data){
    this.str = $('.content-wrap').html();
    data.map(v=>{
        if(v.thumbURL)
            this.str += ` <li class="cw-box" data-url="${v.middleURL}"><img src="${v.thumbURL}" class="cw-box-img" title="${v.fromPageTitle.replace(/<\/?[^>]*>/g,'')}" /></li>`;
    });
    $('.content-wrap').html(this.str);
    this.setBodyBackgroundImage();
    this.loadOnoff = true;
  }

  //设置背景图片
  setBodyBackgroundImage(){
    $('.cw-box').click(function(){
       console.log(this.dataset.url);
        chrome.tabs.executeScript(null,{
          code: ` 
            document.body.style.backgroundImage = "url(${this.dataset.url})";
            document.body.style.backgroundRepeat = "repeat";
            document.body.style.backgroundPosition = "0 0";
            document.body.style.backgroundSize = "contain";  
          `
        });
    })
  }
}

new Popup();

6. background层逻辑实现:

chrome.runtime.onMessage.addListener(function(request, sender, callback) {
    //检测message信息
    switch(request.event)
    {
        case 'getImage':
        //console.log(request.value+request.event);
            getImageRequest({str:request.value,loadIndex:request.loadIndex},(data)=>{
                console.log(data);
                callback(data);
            });
            break;
        default:
            callback({code:0})
            break;
    }
    return true;
});


function getImageRequest({str,loadIndex},callback){
    var per = 30;
    var ctotal = loadIndex * per;
    var url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E5%93%86%E5%95%A6a%E6%A2%A6&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word='+str+'&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn='+ctotal+'&rn='+per;
    fetch(url).then((response)=>(response.json())).then((data)=>{
        callback(data);
    }).catch((error)=>{
        console.log(error);
    });
}

7. 由于刚开始阶段,没有找到api接口,直接采用TP引入simple_html_dom类进行抓包实现,速度较慢,后期决定采用自身的百度图片api的搜索接口:

(1)api搜索接口:

var url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=哆啦a梦&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word='+str+'&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&pn='+ctotal+'&rn='+per;

(2)抓包的url:

$search_str = 'https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1536477037932_R&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&ctd=1536477037932^00_653X974&word='.$this->datas['image_search'];

8. 最终背景图片设置交互展示:

9. 欢迎关注的我的新浪博客地址:小青蛙博客

10. github源码地址:源码直通车

猜你喜欢

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