zoukankan      html  css  js  c++  java
  • 我的第一个油猴脚本--微博超话自动签到

    简介

    用户脚本是一段代码,它们能够优化您的网页浏览体验。安装之后,有些脚本能为网站添加新的功能,有些能使网站的界面更加易用,有些则能隐藏网站上烦人的部分内容。其中常见的有 油猴插件ChromeExtentions

    由于油猴脚本只用一个JS文档,因而相对于ChromeExtentions比较简单。因此便从油猴脚本开始,首先基本的文件架构是:

    // ==UserScript==
    // @name New Script  
    // @namespace Violentmonkey Scripts
    // @match http://ju.outofmemory.cn/entry/360333
    // @grant none
    // ==/UserScript==

    其中一些属性的含义:

    @name :

    脚本名称

    @description:

    脚本功能的描述,显示在脚本标题下面,必填项。

    @namespace:

    @namespace@name 这两个属性被作为脚本的唯一标识符,用户脚本管理器根据它们来判断一个脚本是否已安装

    @include, @exclude, @match:

    描述脚本会在哪些网站上运行。该列表会被解析和展示到脚本的简介页面,并用于脚本的分类。

    @supportURL:

    该脚本的技术支持链接(如:错误反馈系统、论坛、电子邮件等),该链接将显示在脚本的反馈页面。

     

    具体的注释信息

    脚本简介

    第一次编写的脚本是微博超话自动签到,主要借鉴bilibili助手的基本逻辑。本脚本功能实现每日自动签到微博超话

    界面图:

    微博自动签到

    总结:

    1.基于$.ajax()对Deferred理解。

    主要借鉴$.ajax()引发的对Deferred的总结回调、使用Promise封装ajax()、Promise入门

    ajax()是一种网页中常用的异步操作,其写法有两种

    //第一种,传统写法
    $.ajax({
       url:"/xxx",
       type:"get",
       success:function(data){//成功调用后的回调函数},
       error:function(){//失败调用后的回调函数}
    });
    //第二种
    $.ajax({
       url:"/xxx",
       type:"get"
    }).then(success,fail);//$.ajax()返回的是promise对象

    Deffered是一种延迟对象 $.Deffered(),返回Deffered对象

    done(fn) 当成功后调用fn

    fail(fn) 当失败后调用fn

    then(done,fail) done和fail的总写方式

    always(fn) 不管成功或失败都执行

     

    resolve和reject执行,便执行done、fail、then、always方法。

    resolve(value) 告诉对象执行done回调,value是参数,传入done的回调函数 reject(value) 告诉对象执行fail回调,value是参数.传入fail的回调函数

     

    采用第二种写法可以实现链式编程

    const fn=()=>{const p =$.Deferred()
    $.ajax({
       url:"/xxx",
       type:"get"
    }).then(
      (data)=>{p.resolve(data)},
      ()=>{p.reject()}
    );
    return p}

    fn().then((data)=>{
       //成功后的操作,data是resolve传入的参数
       //如果还需要异步执行,可以再定义Deferred对象,以此来实现有顺序的执行
    },()=>{
       //失败后的操作
    })
    2.跨域问题

    由于JavaScript同源策略的限制,脚本只能读取和所属文档来源相同的窗口和文档。ajax请求时可能会请求不同源的网址。

    首先以weibo.com为例说明同源

    URL结果原因
    https://www.weibo.com/dir1/other.html Success 同源
    https://www.weibo.com/dir2/another.html Success 同源
    https://m.weibo.com/1.html Fail 主机不同
    http://www.weibo.com/2.html Fail 协议不同
    https://www.weibo.com:80/3.html Fail 端口不同

    这里用到了两种:

    1. document.domain

    默认情况下,document.domain存放的是载入文档的服务器的主机名,但不能设置为顶级域名,如www.weibo.com 可以设置为weibo.com 但不能设置为com

     

    具有相同的document.domain就处在同域名的服务器上

    此处借鉴:通过document.domain实现跨域访问

    1. CORS(跨域资源共享)

    CROS是一种跨域访问机制,可以实现Ajax的跨域访问

    需配置

    //ajax中的配置
    xhrFields.withCredentials = true
    crossDomain = true
    3.添加DOM元素

    如果需要向网页中添加按键、css样式等等,就需要添加DOM元素,

    添加方法

    如果需要引入CSS样式链接

    $('head').append('<link rel="stylesheet" href="样式的链接" />')

    上面的方法主要采取的jquery的方法,也可以用原生JS

    const addCSS = (context) => {
           const style = document.createElement('style');
           style.type = 'text/css';
           style.innerHTML = context;
           document.getElementsByTagName('head')[0].appendChild(style);
      };//该方法用于添加CSS样式

     

    4.检查类型

    一种是通过typeof,可以判断undefined、boolean、string、number、function

    用typeof判断数据类型

    可以看到typeof对 对象、数组、null判定为object,有一定的缺陷。

    另一种方法用Object.prototype.toString.call判断

     

    用Object.prototype.toString.call来判断

    可以看到用此方法可以解决之前的混淆

    除此之外,脚本也用到了isNaN()判断是否为数字,如果为数字则为false,如果不是数字,则为true。

     

    parseInt(string,radis)将其它类型转换为Int类型,第二个参数为进制

    注意: 只有字符串中的第一个数字会被返回。

    注意: 开头和结尾的空格是允许的。

    注意:如果字符串的第一个字符不能被转换为数字,那么 parseInt() 会返回 NaN。

    5.localStorage

    window的localStoragesessionStorage储存k/v对的数据,localStorage 中的键值对总是以字符串的形式存储。

    localStorage用于长久保存整个网站数据。

    方法:

    localStorage.setItem('对象名','存储的数据') 存储

    localStorage.getItem('对象名') 读取

    localStorage.removeItem('对象名') 移除

    localStorage.clear() 移除所有

     

    如果存储的数据是JSON的类型,这可以用JSON.stringify()

    JSON.parse()来进行JSON对象和String对象的类型转换

     

    6.一些以后可能用到的方法
    const tz_offset = new Date().getTimezoneOffset() + 480;

    const ts_s = () => Math.round(ts_ms() / 1000);

    const ts_ms = () => Date.now();

    const checkNewDay = (ts) => {
           // 检查是否为新的一天,以UTC+8为准
           const t = new Date(ts);
           t.setMinutes(t.getMinutes() + tz_offset);
           t.setHours(0, 0, 0, 0);
           const d = new Date();
           d.setMinutes(t.getMinutes() + tz_offset);
           return (d - t > 86400e3);//86400秒为一天的时间
      };

    const runUntilSucceed = (callback, delay = 0, period = 100) => {
           setTimeout(() => {
               if (!callback()) runUntilSucceed(callback, period, period);
          }, delay);
       //如果执行的函数返回值为空,就继续执行,直到callback返回值
      };

    let API={
    processing: 0,
    ajax: (settings) => {
    if (settings.xhrFields === undefined) settings.xhrFields = {};
    settings.xhrFields.withCredentials = true;
               jQuery.extend(settings, {
                   url: (settings.url.substr(0, 2) === '//' ? '' : '//weibo.com/') + settings.url,
                   method: settings.method || 'GET',
                   crossDomain: true,
                   dataType: settings.dataType || 'json'
              });//jquery.extend用于对象的连接
               const p = jQuery.Deferred();
               API.runUntilSucceed(() => {
                   if (API.processing > 8) return false;
                   ++API.processing;
                   return jQuery.ajax(settings).then((arg1, arg2, arg3) => {
                       --API.processing;
                       p.resolve(arg1, arg2, arg3);
                       return true;
                  }, (arg1, arg2, arg3) => {
                       --API.processing;
                       p.reject(arg1, arg2, arg3);
                       return true;
                  });
              });
               return p;
          }  
    }
     
  • 相关阅读:
    DOM性能小记
    利用tween.js算法生成缓动效果
    小游戏(锅打灰太狼)
    DOM应用实例(寻找房祖名)
    学习总结——DOM
    图片预加载
    删除src值为空的img标签
    2019-08-17 纪中NOIP模拟B组
    [SCOI2015] 小凸玩矩阵
    [JZOJ4899] 雪之国度
  • 原文地址:https://www.cnblogs.com/deus/p/11516245.html
Copyright © 2011-2022 走看看