[initial experience of oil monkey script writing] copy title and location

Knowledge points gained from [one click Copy of web page title and address (oil monkey script)]

Article update: July 19, 2021 15:26:07

preface

I named my little blue button "Fu Niu", which means "button (NIU) used to duplicate (Fu) system".

I initially completed the function around May 27, 2021. It seems that there will be a local life interview in Ali a few days later. At that time, I didn't have any works. I originally planned to take this out if the interviewer asked me what I had done, As a result, there was an accident during the interview: the interviewer first called me and told me to take a written test for about 40 minutes, and then called me. The performance of the written test was very poor, because I didn't learn much about JavaScript at that time. There was Promise in the written test, and I was confused at that time, I didn't learn it at that time... Then I left a sentence in the answer area: I'm definitively a vegetable dog... About 40 minutes later, I stared at the mobile phone screen, and the interviewer did call me, but unexpectedly, my mobile phone intercepted the phone, and the interviewer didn't call me after that, Naturally, I can't call back... I watched a conversation opportunity be cleverly intercepted by my mentally retarded mobile phone, Gan! The key is that for this interview, I opened a room in a small hotel for three hours for the first time in my life. As a result... Even if I received the call, I probably couldn't pass, but it was still very uncomfortable

0. Effect

1. How to write oil monkey script

Update: July 19, 2021 10:59:43

reference resources: Chrome extended "oil monkey" script development

Update: July 19, 2021 11:15:33

reference resources: GM_* APIs - Violentmonkey

reference resources: Tampermonkey · frequently asked questions

reference resources: Metadata Block - GreaseSpot Wiki

reference resources: Oil monkey scripting tutorial_ After that is the guest - CSDN blog

reference resources: How to develop a tampermonkey script - a simple book

reference resources: OpenUserJS

reference resources: How to learn oil monkey script writing- Know

reference resources: How to write an oil monkey script by yourself_ Baidu search

Update: 11:13:13, July 19, 2021

reference resources: Oil monkey script rules - Aaxuan - blog Park

reference resources: Oil monkey script rules_ Mcfeng blog CSDN blog

2. JavaScript read clipboard

Update: 11:34:13, July 19, 2021

reference resources: Clipboard operation Clipboard API tutorial - Ruan Yifeng's network log

reference resources: Browser native clipboard navigator Clipboard and document Use of execcommand and Vue clipboard_ Umbrella_Um blog - CSDN blog

// ==UserScript==
// Script name
// @name copy title and address (myFirstScript)
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description copy title and address (myFirstScript)
// @author       LiarCoder
// Which pages are effective? Wildcards are supported
// @match        *://*/*
// @grant        none
// ==/UserScript==

I think it can be solved after changing the above @ match parameter to *: / / * / * / Ruan Yifeng blog The bug that failed to use my script still didn't work. Later, I saw the error [unable to find writetext attribute from undefined] through observation on the console, which means it's Navigator clipboard. writeText(result); There is something wrong with this sentence. Through the console test of different web pages, it is found that there is navigator in other web pages The clipboard attribute is, and the writetext method can also be used, so I glanced at Ruan Yifeng's blog about clipboard: http://www.ruanyifeng.com/blog/2021/01/clipboard-api.html , the error is found: Chrome browser stipulates that only https protocol pages can use this API. I tried to add an s after HTTP and then enter. I found that I could jump to the page with the same content, and the protocol became https. So I began to find a way to convert HTTP into https, but I didn't find the appropriate answer. Later, I remembered that there were many attributes related to the page address in the location object, so I began to experiment and found location Protocol is what I'm looking for. At first
I want to replace http with https through regular expression, and then let the browser jump to the web page under https protocol again. Later, I found that I just need to directly check location Just re assign the value of protocol, so you are using navigator Make a judgment before the clipboard interface. If the current page is not https protocol, replace it with https!

if (location.protocol !== 'https:') {
    location.protocol = 'https:';
}
navigator.clipboard.writeText(result);

After the experiment, I solved my problem perfectly. It's just that the web page with http protocol needs to jump again, which takes a little more time.

3. Generic createEle ment function

// This function is used to create a page element in the style of < elename k = "attrs [k]" > text < / elename >
function createEle(eleName, text, attrs){
    let ele = document.createElement(eleName);
    // innerText, that is, < p > text, will be added here</p>
    ele.innerText = text;
    // The type of attrs is a map
    for (let k in attrs) {
        // Traverse attrs and add the desired attributes to ele node
        ele.setAttribute(k, attrs[k]);
    }
    // Return node
    return ele;
}

4. Iframe tag related issues (iframe tag; self and this; homology restriction)

I first found that the problem caused by iframe was that Funiu appeared next to the text input box in the QQ email Notepad (this was unexpected), and a Funiu appeared in the upper left corner of the web page (this was expected). I didn't care at that time, Only the domain name of QQ mailbox is added to the exclusion URL of oil Monkey (oil monkey allows developers to set something similar to the blacklist URL list. In this URL, the oil monkey script does not work, and supports regular expressions). The problem is solved temporarily. Later, on the login interface of Alibaba's campus recruitment official website, I found that in addition to the Funiu that should appear in the upper left corner of the page, Funiu also appeared in the login box component. So I decided to solve this problem seriously.

I located the relevant elements through the developer tool and found that the login box is embedded in a < iframe > tag, which also has a complete HTML page structure.

<iframe id="alibaba-login-box" src="......">
	#document
	<!DOCTYPE html>
	<html lang="en">
  	<head>
    	<title>Sign in</title>
		......
  	<head>
  	<body>
    	......
  	</body>
	</html>
</iframe>

So, we can find that two body elements appear in a web page, because my Funiu is through document body. appendChild(); In this way, it is added to the DOM structure of the page, so there are two lucky girls in the page (if there are multiple iframe tags in a page, there will naturally be multiple lucky girls, such as in -HTML (Hypertext Markup Language) | MDN On this page, there may be multiple figures of Fu Niu). So I began to find a way to judge whether the current page is in the < iframe > tag. Finally, after testing, the following writing method is adopted.

// document.body.appendChild(style); //  This writing method will cause the script to be selected in the body tag of the < iframe > tag html document
// self === top is used to judge whether the current page is in the < iframe > tag. If it is true, it means it is not in the < iframe > tag
if(window.self === window.top) {
    // The following judgment is the writing method in the oil monkey script of [web page restriction lifting (change)], which feels more comprehensive.
    // But in fact, the purpose of my initial change was to solve the problem that my script did not work in Ruan Yifeng's Weblog,
    // However, it was later found that the problem was not here, but that the @ match parameter was written without considering that the network protocol was http,
    // So it was written as @ match https: / / * / *, and the protocol used by Ruan Yifeng's blog is http,
    // So I can't show my Fu Niu. It turned out that there was no match at all, so it was changed to @ match *: / / / * /,
    // In this way, all web pages will theoretically have my Fu Niu
    if (document.querySelector('body')){
        document.body.appendChild(style);
    } else {
        document.documentElement.appendChild(style);
    }
    // document.querySelector('body').appendChild(style);
    // document.body.appendChild(style);
}

Update: May 31, 2021 23:46:49

reference resources: (method 3 is tested to be effective) js determines whether an element is in iframe - starry sky - blog Garden

reference resources: (not tried) html determines whether the current page is in iframe_ Small single blog column - CSDN blog_ Determine whether the page is in iframe

reference resources: (after testing, IT seems not easy to use) how to check whether the elements are in iframe - IT House - programmer software development technology sharing community

reference resources: Node.ownerDocument - Web API interface reference | MDN

reference resources: -HTML (Hypertext Markup Language) | MDN

reference resources: window.frameElement - Web API interface reference | MDN

reference resources: JavaScript self and this use summary - ued - blog Garden

// js determines whether an element is in iframe
//1. Mode 1 (it doesn't seem to work in my script, and the following "IFRAME" seems to have to be capitalized)
if (self.frameElement && self.frameElement.tagName == "IFRAME") {
  alert('stay iframe in');
}
//2. Mode 2 (never tried)
if (window.frames.length != parent.frames.length) {
  alert('stay iframe in');
}
//3. Mode 3 (effective through personal test)
if (self != top) { 
  alert('stay iframe in');
}

reference resources: Homology restriction (iframe and multi window communication) - JavaScript tutorial - Network Channel

5. The display style of Funiu in some web pages is different from that expected

It is mainly to adjust the following initialBtnStyle. Note that the following \ is because one line is too long. Use it to split into multiple lines. JavaScript knows what this means.

let initialBtnStyle = '#copy-title-and-location {position: fixed; top: 100px; left: -100px; z-index:  2147483647; opacity: 0.5; background-image: none;\
background-color: #0084ff !important; margin: 5px 0px; cursor:pointer; font-size: 12px; line-height: 17px; width: auto; font-family: Arial, sans-serif;\
color: #fff; border-radius: 3px; border: 1px solid; padding: 3px 6px ; transition: left, 0.5s; height: 26px;}';
  1. At first, I found that my Funiu display style was a little different on Zhihu and Baidu pages, and it was significantly larger on Zhihu pages. After debugging by developer tools, it is found that different web pages have relevant style settings for higher-level elements such as body and html, and their child elements inherit some settings. I specially added font size and line height attributes in the CSS style settings above, and wrote the relevant values. I found that my script small buttons sometimes have different display effects in different web pages, so if you want a consistent display effect, just write these two attributes.

  2. On the web page of this blog Garden( https://www.cnblogs.com/llhthinker/p/6719779.html )The display effect of my button is different from that expected. I didn't respond to any adjustment. Specifically, my Funiu is not displayed on the web page. But I saw through the developer tools that my website was full of my website, but it was hidden on the left side of the page (which is somewhat like the negative value of the left value), so I adjusted the relevant attribute values in my developer's tools. Finally, I found that I set the width value of Funiu to a fixed value: 124px, which solves the problem that my Funiu is not displayed on this page. There is also a small episode in the middle, that is, I wrote the English colon in width: 124px into Chinese colon:, but I found that I had changed the corresponding value, but there was no response. Later, I saw a warning sign in front of the width attribute in the Google developer tool. I moved the mouse up and found that it prompted: Unknown property name. I realized that I had typed the colon wrong... (Gan, the clown was myself)

  3. At 23:20:01 on June 20, 2021, I found that the button style was a little strange on Apple's official website, so I added the font family attribute and changed the width from the fixed 124px to auto.

  4. At 00:47:55 on July 13, 2021: https://www.linuxidc.com/Linux/2016-11/137495.htm It was found that the height of the button was wrong. Through the developer tool, it was found that the web page set the height of the button element to a fixed 22px, so I added height: 26px to the above style to fix the height to an appropriate value.

  5. At 00:33:02 on June 22, 2021, I found that the copy icon of my button was unusually large on the official website of outlook, and the style did not meet the expectations. Through the console, I found that the width attribute of img was set to 100% by default. Just try to set it to auto.

    let imgTag = createEle('img', '', {src:icon, style: "width: auto; vertical-align: middle; margin-left: 10px; border-style: none;text-align: center;display: inline-block;margin-bottom: 2px"});
    

6. Get the local time and transform it into the format you want

At first, my script didn't include: [update: xx: xx: xx, xx, xx]. Later, I thought I should write down the log writing time, so I added this function. However, none of the methods provided by JavaScript for obtaining time can directly return the format I want above, so I made a time format I want on top of the native methods provided by JavaScript.

let date = new Date();
// native method 
date.toLocaleTimeString();
"2 pm:38:52"
// Transformation method (there is a small problem here, that is, at 12 p.m., the following method will return 24:xx:xx instead of 00:xx:xx I want, but it doesn't hurt
date.toLocaleTimeString('chinese', {hour12: false});
"14:38:38"
// native method 
date.toLocaleDateString();
"2021/7/19"
// Transformation method
date.toLocaleDateString().replace('\/', 'year').replace('\/', 'month') + 'day'
"2021 July 19"

// Final format
let timeStamp = date.toLocaleDateString().replace('\/', 'year').replace('\/', 'month') + 'day' + date.toLocaleTimeString('chinese', {hour12: false});
"2021 July 19, 2014:38:38"

Update: July 19, 2021 14:50:02

reference resources: JavaScript related tool code - cloud + community - Tencent cloud

reference resources: Date.prototype.toLocaleTimeString() - JavaScript | MDN

7. base64 and picture rotation

The following online conversion tools are the best I've tried for several times.

Update: July 19, 2021 14:55:14

reference resources: base64 to picture - love information tool

Keywords: Javascript css

Added by gangsterwanster1 on Sun, 16 Jan 2022 21:21:55 +0200