Safari脚本编辑使用体验

背景

背景是这样的,我在用 Safari看hackingwithswift这个网站时,感觉上方的一直固定的红色的和黑色的两条,如下图,太醒目了,于是便想,如何能把它们移除.

实现

首先查看这两个是怎么实现的,右键选择Inspect Element,选中对应两块区域,查看,如下:

知道了两个模块的classid后,下一步是在Console中,尝试获取,看能否实现,如下:

可以发现能够获取到,下一步就来考虑如何通过Safari Extension脚本编辑来实现自动移除.

首先,安装一个 Safari Extension, Userscripts或Stay-Userscript Extension,这两个二选一即可,针对自己写javascript这种情况,推荐使用第一个,因为Userscripts的编辑界面更好用.

安装后,打开,在 Safari Extension界面,启用,如下:

然后如下图,点击Open Extension Page,

然后点击New Javascript,就进入 js脚本编辑页面,

进入 js脚本编辑页面后,可以看到页面如下,其中

  • @name 是这个文件的名字,或者这个js脚本的名字
  • @description 是这个文件的功能描述
  • @match 是要匹配的网址,如果浏览器地址栏输入的网址与@match 进行匹配,如果返回 true 则会调用$(function(){})入口方法

然后问题来了,具体代码怎么写,没正经写过 js 代码,更没写过油猴脚本,要怎么开始呢?很简单,借鉴,

之前安装了xxx 广告清理,打开看里面的代码结构和格式,先确认格式怎么写,在确认里面功能怎么实现,发现大致格式如下:

(function() {
    'use strict';
    
    xxx

    function clearAD(){
        xxx
    }

    xxx

    setTimeout(()=>{clearAD();},2000);
})();

所以按照同样的逻辑来实现,只需要把clearAD的方法变为removeNavbarAndSkybar,然后方法内部实现移除navbarskybar即可.

道理是这个道理,那方法内部怎么实现还是不知道,怎么办?接着借鉴,参考如下代码,可以发现是通过document.querySelectorAll方法获取classid的,然后 for 循环移除

function clearAD(){
        if(!document.querySelectorAll)return;
        var mAds=document.querySelectorAll(".ec_wise_ad,.ec_youxuan_card,.page-banner"),i;
        for(i=0;i<mAds.length;i++){
            var mAd=mAds[i];
            mAd.remove();
        }
        var list=document.querySelectorAll("#content_left>div,#content_left>table");
        for(i=0;i<list.length;i++){
            let item = list[i];
            let s = item.getAttribute("style");
            if (s && /display:(table|block)\s!important/.test(s)) {
                item.remove();
            }else{
                var span=item.querySelector("div>span");
                if(span && span.innerHTML=="广告"){
                    item.remove();
                }
                xxx
            }
        }
    }

所以参照上面的代码,实现自己的如下:

// ==UserScript==
// @name        Remove Hacking With Swift Navbar and skybar
// @description Remove Hacking With Swift Navbar and skybar
// @match       *://*/*
// ==/UserScript==

(function() {
    'use strict';
    
    function removeNavbarAndSkybar(){
        var mAds=document.querySelectorAll(".navbar"),i;
        for(i=0;i<mAds.length;i++){
            var mAd=mAds[i];
            mAd.remove();
        }
        var list=document.querySelectorAll("#hws-latest-tutorial");
        for(i=0;i<list.length;i++){
            let item = list[i];
            item.remove();
        }
    }
    
   setTimeout(()=>{removeNavbarAndSkybar();},2000);

})();

然后点击右下角的保存,再点击左边的开启,如下图所示:

然后打开网址: https://www.hackingwithswift.com/books/ios-swiftui/reading-text-from-the-user-with-textfield, 可以发现一直固定的红色的和黑色的,都去除了,基本上就完成了.

优化的地方:

  1. 仔细看上面脚本中的代码,会发现最终的调用是通过setTimeout(){}延时来调用的,这个延时合不合理?会不会有什么问题?改成判断网页load完成后再移除是不是更好?
  2. 上面的代码是为了针对hackingwithswift网站移除对应的内容,但是,脚本中却没有针对域名的判断,是否可以添加?

最终代码如下:

// ==UserScript==
// @name        Remove Hacking With Swift Navbar and skybar
// @description Remove Hacking With Swift Navbar and skybar
// @match *://www.hackingwithswift.com/* 
// 
// ==/UserScript==

(function() {
    'use strict';
    
    function removeNavbarAndSkybar(){
        var mAds=document.querySelectorAll(".navbar"),i;
        for(i=0;i<mAds.length;i++){
            var mAd=mAds[i];
            mAd.remove();
        }
        var list=document.querySelectorAll("#hws-latest-tutorial");
        for(i=0;i<list.length;i++){
            let item = list[i];
            item.remove();
        }
    }
    
    window.addEventListener('load', function() {
        removeNavbarAndSkybar();
    }, false);
})();

参考

  • 油猴脚本 @match 正则匹配问题
本文转载于网络 如有侵权请联系删除

相关文章

  • 百度分享调用代码不符合W3C标准的解决办法

    换上新主题Hstyle以后,站长也选择了百度分享,昨晚简单测试一下W3C,发现百度分享调用代码居然不符合W3C标准,google了一下,发现还是有前辈找到了解决办法。话说这个问题早在半年多前就有朋友反馈给百度了,但是至今没有官方的解决方案出来,咋回事呢?站长使用的百度分享调用代码默认为:1 2 3 4 5 6 7<!--BaiduButtonBEGIN--> <scripttype="text/javascript"id="bdshare_js"data="type=slide&img=0&uid=11321"></script> <scripttype="text/javascript"id="bdshell_js"></script> <scripttype="text/javascript"> document.getElementById("bdshell_js

  • echarts在react中的引入使用(俩种方法)

    一.第一步先看看你的echarts版本。小于5.0版本的可以使用以下方法:先安装:npmiecharts@4.0.4--savenpmiecharts-for-react--save1.原始echarts导入importReactfrom'react' //引入ECharts主模块 importechartsfrom'echarts/lib/echarts' //引入饼图 import'echarts/lib/chart/bar' //引入提示框和标题组件 import'echarts/lib/component/tooltip'; import'echarts/lib/component/title'; import'echarts/lib/component/legend'; import'echarts/lib/component/markPoint';复制实例化echartscomponentDidMount(){ //基于准备好的dom,

  • 3.2spring源码系列----循环依赖源码分析

    首先,我们在3.1spring5源码系列--循环依赖之手写代码模拟spring循环依赖中手写了循环依赖的实现.这个实现就是模拟的spring的循环依赖.目的是为了更容易理解spring源码.下面我们就进入正题,看看spring的循环依赖源码.一、getBean整体流程目标很明确了,就是要看看spring如何解决循环依赖的.代码入口是refresh()#finishBeanFactoryInitialization(beanFactory);二、拆解研究流程中的每一步调用方法beanFactory.preInstantiateSingletons();实例化剩余的单例bean.为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类,postProcessor等.2.1入口1@Override 2publicvoidpreInstantiateSingletons()throwsBeansException{ 3if(logger.isTraceEnabled()){ 4logger.trace("Pre-instantiatingsingletonsin"+t

  • 从 PageRank Example 谈 Spark 应用程序调优

    最近做了关于SparkCache性能测试,开始是拿BigData-Benchmark中SparkKMeans来作为测试基准,分别测试各种Cache下应用程序的运行速度,最后使用SparkPageRankExample来验证。在做PageRank测试时,发现有很多有趣的调优点,想到这些调优点可能对用户来说是普遍有效的,现把它整理出来一一分析,以供大家参考。 BigData-Benchmark中的SparkPageRank采用的是Spark开源代码里的PageRank样例代码,原理及代码实现都比较简单,下面我简单地介绍下。PageRank基本原理介绍PageRank的作用是评价网页的重要性,除了应用于搜索结果的排序之外,在其他领域也有广泛的应用,例如图算法中的节点重要度等。假设一个由4个页面组成的网络如下图所示,B链接到A、C,C链接到A,D链接到所有页面。那么A的PR(PageRank)值分别来自B、C、D的贡献之和,由于B除了链接到A还链接到C,D除了链接到A还链接B、C,所以它们对A的贡献需要平摊,计算公式为:简单来说,就是根据链出总数平分一个页面的PR值:对于上图中的A页面来说,它

  • OLTP与OLAP的区别精简总结

    1、当今的数据处理大致可以分成两大类: 联机事务处理On-LineTransactionProcessing 联机分析处理On-LineAnalyticalProcessing2、二者特性的不同,决定了对资源需求的偏重01-1OLTP(实时交易库大量短事务对IO要求高)一、面向交易的实时处理系统OLTP OLTP是传统的关系型数据库的主要应用,主要是基本的、日常的事务处理,记录即时的增、删、改、查,比如在银行存取一笔款,就是一个事务交易。 也称为实时系统(RealtimeSystem)。衡量联机事务处理系统的一个重要性能指标是系统性能,具体体现为实时响应时间(ResponseTime),即用户在终端上送入数据之后,到计算机对这个请求给出答复所需要的时间。二、OLTP特点 1、实时性要求高; OLTP数据库旨在使事务应用程序仅写入所需的数据,以便尽快处理单个事务。 2、数据量不是很大; 3、交易一般是确定的,所以OLTP是对确定性的数据进行存取(比如存取款都有一个特定的金额); 4、支持大量并发用户定期添加和修改数据。 并发性要求高并且严格的要求事务的完整、安全性(比如这种情况:有可能你

  • Vue手把手带你撸项目系列之动态面包屑

    面包屑应该是我们在项目中经常使用的一个功能,一般情况下它用来表示我们当前所处的站点位置,也可以帮助我们能够更快的回到上个层级。今天我们就来聊聊如何在Vue的项目中实现面包屑功能。以下案例都是使用Element-UI进行实现。最笨的方式首先我们想到的最笨的方法就是在每个需要面包屑的页面中固定写好。<template> <divclass="example-container"> <el-breadcrumbseparator="/"> <el-breadcrumb-item v-for="(item,index)inbreadList" :key="index" :to="{path:item.path}" >{{item.name}}</el-breadcrumb-item> </el-breadcrumb> </div> </template> <script> exportde

  • 数组排序

      1、 functionisArr(arr){ varlen=arr.length; for(vari=0;i<len;i++){ for(varj=0;j<len-1-i;j++){ if(arr[j]>arr[j+1]){ vartemp=arr[j];//交换 arr[j]=arr[j+1]; arr[j+1]=temp; } } } returnarr }复制     

  • canvas性能-drawImage渲染图片

    canvas性能-绘制图片 目录canvas性能-绘制图片canvas绘制图片drawImageputImageDatacreatePattern测试绘制耗时drawImageImage类型ImageBitmap类型HTMLCanvasElement类型putImageData结论 canvas绘制图片 一般我们绘制图片会用到的方法是drawImage和putImageData,还有作为测试环境使用的createPattern drawImage 描述: 使用方式: ctx.drawImage(image,sx,sy,swidth,sheight,x,y,width,height) 复制 image的类型: HTMLImageElement:这些图片是由Image()函数构造出来的,或者任何的img元素 HTMLVideoElement:用一个HTML的video元素作为你的图片源,可以从视频中抓取当前帧作为一个图像 HTMLCanvasElement:可以使用另一个canvas元素作为你的图片源 ImageBitmap:这是一个高性能的位图,可以低延迟地绘制,它可以从上述的所有源

  • Node之path

    path path模块提供了一些实用工具,用于处理文件和目录的路径。 path.basename(path[,ext]) path ext可选的文件扩展名。 返回:path的最后一部分 path.basename('/目录1/目录2/文件.html'); //返回:'文件.html' path.basename('/目录1/目录2/文件.html','.html'); //返回:'文件' 复制 path.dirname(path) 返回path的目录名 path.dirname('/目录1/目录2/目录3'); //返回:'/目录1/目录2' 复制 path.extname(path) 返回path的扩展名 path.extname('index.html'); //返回:'.html' path.extname('index.coffee.md'); //返回:'.md' path.extname('index.'); //返回:'.' path.extname('index'); //返回:'' path.extname('.index'); //返回:'' pat

  • how-dbt-fails

    一篇值得学习的dbt分析文章,内容还是比较有意思的https://benn.substack.com/p/how-dbt-fails

  • win7用户文件夹转移到D盘

      用户文件夹转移到D盘: 在安装Windows7的过程中,要求输入用户名及密码的时候,先不如输入任何信息, 按“Shift+F10”呼出DOS窗口,输入以下命令:   ROBOCOPY"C:\Users""D:\Users"/E/COPYALL/XJ RMDIR"C:\Users"/S/Q   MKLINK/J"C:\Users""D:\Users"   而后关闭DOS窗口,按部就班继续安装直至完成。 如此安装的Windows7,所有“用户特殊文件夹”(UserSpecialFolder)的内容都已经被设置在D盘(非系统盘)上。 我经过试验,此方法可靠!

  • Java读取资源

    publicclassTest1110{ publicstaticvoidmain(String[]args)throwsIOException{ ResourcePatternResolverresolver=newPathMatchingResourcePatternResolver(); org.springframework.core.io.Resource[]resources=resolver.getResources("classpath:img/logo.jpg"); org.springframework.core.io.Resourceresource=resources[0]; System.out.println("getDescription:"+resource.getDescription());//classpathresource[img/logo.jpg] System.out.println("getFilename:"+resource.getFilename());//logo.jpg } }复制  

  • 西工大计算机夏令营面试

    西工大夏令营面试 感觉面试难度还是比较小,奈何我太菜。线代问题那个真的丢脸。还有面试不提前说序号,随机叫号,运气太差,排到了最后几个,屏幕前等了六个小时,差评。(从面试前的紧张,到开始偶尔刷视频,打游戏消磨了,emmm) 1.阅读一段一百字左右的短文,然后翻译。 大意:目前数据规模不断提高了,手工处理数据已经不现实了,需要借助计算机科学的手段,例如神经网络,决策树,支持向量机等工具。 (哎,英语读的自己都觉得别扭) 2.线性代数:矩阵的特征值和特征向量计算方式及意义。 (我哭了,前两个才复习了,现在啥都不会) 对于一个方阵A,如果存在非零向量\(x\),使得\(Ax=mx\),\(x是特征向量,m是特征值\) 3.高数:梯度 梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大。 (基本答对) 4.数据结构:说几种排序算法的复杂度 只说了四种,丢脸了。都没有答堆排序和桶排序 5.编程经历 主要说的是ACM经历 6.是否了解意愿导师的方向 了解,CV+NLP 7.除了ACM之外的编程经历,有没

  • npm install 装本地一直安装全局问题

    想用npm安装一些模块,不管怎么装,一直装作全局。   以为是node有问题,重装了N次,却还发现这个问题。 困惑几天无果, 偶然间通过此文章发现,npm存在配置文件:https://www.sitepoint.com/beginners-guide-node-package-manager/ cat.npmrc之后 发了日了狗的global=true 果断艹为false。 一切正常~~~  

  • Hive DQL详解

      1、select语法 SELECT[ALL|DISTINCT]select_expr,select_expr,... FROMtable_reference [WHEREwhere_condition] [GROUPBYcol_list] [CLUSTERBYcol_list |[DISTRIBUTEBYcol_list][SORTBYcol_list] ] [LIMITnumber]复制   SELETC声明可以是union的一部分或者是另一个查询的子查询。   table_reference代表被查询的对象,可以是一个table、view、join结构、或者子查询。   例如:查询表t1的所有列。   SELECT*FROMt1;   1.1WHERE条件   where条件是一个boolean表达式。   例如:下面这个查询语句返回结果是sales记录中在USregion里并且amount>10的记录。   SELECT*FROMsalesWHEREamount>10ANDregion='US';   Hive的where条件里不支持IN,

  • 跟着刚哥学习Spring框架--JDBC(六)

    Spring的JDBC框架 SpringJDBC提供了一套JDBC抽象框架,用于简化JDBC开发。 Spring主要提供JDBC模板方式、关系数据库对象化方式、SimpleJdbc方式、事务管理来简化JDBC编程 Spring提供了3个模板类: JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。 NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。 SimpleJdbcTemplate:利用Java5的特性,比如自动装箱、通用(generic)和可变参数列表来简化JDBC模板的使用。 JdbcTemplate主要提供以下4类方法: execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句; update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句; query方法及queryForXXX方法:用于执行查询相关语句; call方法:用于执行存储

  • 根据代码中的端口号找到部署的服务文件

    背景 通过代码监听的端口号,找到部署服务的文件地址 step1  lsof-i:8080找到对应的端口号监听进程pid     step2根据进程pid查看/proc/$pid文件 ll/proc/401928  

  • 更新yum源

    cd/etc/yum.repos.d复制 备份一下原来的yum源 mvCentOS-Base.repoCentOS-Base.repo.bk复制 下载新的CentOS-Base.repo到/etc/yum.repos.d/如下的源用一个就好,三条命令选其一 //更新为阿里云的源 wget-O/etc/yum.repos.d/CentOS-Base.repohttp://mirrors.aliyun.com/repo/Centos-6.repo //更新为163的源 wget-O/etc/yum.repos.d/CentOS-Base.repohttp://mirrors.163.com/.help/CentOS6-Base-163.repo //更新为搜狐的源 wget-O/etc/yum.repos.d/CentOS-Base.repohttp://mirrors.sohu.com/help/CentOS-Base-sohu.repo复制 运行yummakecache生成缓存 yumcleanall yummakecache复制 ❤本博客只适用于研究学习为

  • vs code 开发小程序会用到的插件

    主要介绍一下几个vscode插件,在vscode中搜索插件关键字点击安装即可。 1)vscodeweappapi, 语法结构api; 2)minapp-vscode 3)vscodewxml 4)vscode-wechat 5)EasyWXLESS 6)小程序助手

  • 记录两个http调用方法

    /***http发送post请求*@paramurl*@paramparam*@return*/publicstaticStringsendPost(Stringurl,Stringparam){PrintWriterout=null;BufferedReaderin=null;Stringresult="";try{URLrealUrl=newURL(url);//打开和URL之间的连接URLConnectionconn=realUrl.openConnection();//设置通用的请求属性conn.setRequestProperty("accept","*/*");conn.setRequestProperty("connection","Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)");conn.setRequestProperty("Content-Type","application/json");//发送POST请求必

  • 六角形

    importturtle turtle.color("blue","red") turtle.begin_fill() whileTrue: turtle.forward(50) turtle.right(120) turtle.forward(50) turtle.left(60) ifabs(turtle.pos())<1: break whileTrue: turtle.right(60) turtle.fd(50) ifabs(turtle.pos())<1: break turtle.end_fill() turtle.hideturtle()复制  

相关推荐

推荐阅读