今是昨非

今是昨非

日出江花红胜火,春来江水绿如蓝

Safari Script Editing Experience

Background#

The background is like this. When I was using Safari to visit the "hackingwithswift" website, I felt that the two fixed red and black bars at the top were too eye-catching, as shown in the figure below. So I wanted to know how to remove them.

image

Implementation#

First, let's see how these two bars are implemented. Right-click and select "Inspect Element" to select the corresponding areas and view them, as shown below:

image

After knowing the class or id of the two modules, the next step is to try to retrieve them in the Console to see if it can be achieved, as shown below:

image

It can be found that they can be retrieved. The next step is to consider how to automatically remove them through "Safari Extension Script Editing".

First, install a Safari Extension, Userscripts or Stay-Userscript Extension, either of these two can be chosen. For situations like writing your own JavaScript, it is recommended to use the first one because the editing interface of Userscripts is more user-friendly.

After installation, open it and enable it in the "Safari Extension" interface, as shown below:

image

Then, as shown in the figure below, click "Open Extension Page",

image

Then click "New Javascript" to enter the JavaScript script editing page,

image

After entering the JavaScript script editing page, you can see the page as follows, where

  • @name is the name of this file or the name of this JavaScript script
  • @description is the functional description of this file
  • @match is the URL to be matched. If the URL entered in the browser's address bar matches @match and returns true, the $(function(){}) entry method will be called
image

Then the question arises, how to write the specific code? I haven't written JavaScript code seriously, let alone a Greasemonkey script. How should I start? It's simple, learn from others.

I previously installed "xxx Ad Cleaner" and opened it to see its code structure and format, first confirm how to write the format, and then confirm how to implement the functionality inside. I found that the general format is as follows:


(function() {
    'use strict';
    
    xxx

    function clearAD(){
        xxx
    }

    xxx

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

So, following the same logic, I just need to change the method clearAD to removeNavbarAndSkybar, and then implement the removal of the navbar and skybar inside the method.

The principle is clear, but I don't know how to implement it inside the method. What should I do next? Continue to learn from others. Refer to the following code, you can find that it uses the document.querySelectorAll method to retrieve the class or id, and then removes them in a for loop.

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
            }
        }
    }

So, referring to the above code, the implementation of my own code is as follows:


// ==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);

})();

Then click "Save" in the lower right corner, and then click "Enable" on the left side, as shown below:

image

Then open the website: https://www.hackingwithswift.com/books/ios-swiftui/reading-text-from-the-user-with-textfield. You can see that the fixed red and black bars have been removed, and the task is basically completed.

Optimization:

  1. If you carefully look at the code in the script above, you will find that the final call is made through setTimeout(){} with a delay. Is this delay reasonable? Will there be any problems? Is it better to change it to remove after judging that the webpage has finished loading?
  2. The above code is for removing specific content on the "hackingwithswift" website, but the script does not have a domain name judgment. Can it be added?

The final code is as follows:


// ==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);
})();

References#

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.