编写自用油猴脚本踩坑记录
前言
春节期间,我叔叔问我这个不太懂前端的Jvav后端有没有什么办法可以帮他修改一下网页上现实的内容,于是就有了这次第一次编写油猴脚本的尝试。
需求
户外作业时,需要使用手机浏览器查看公司的一个页面信息,这个页面一共有16个卡片风格的信息块,一个信息块在手机上要滑动3个屏幕高度(逆天)。每次要从这么大一个信息块中找到有用的3条信息,搜索排序功能也是非常难用。需要将16个信息块中有用的几条信息,汇总起来,便于查看。
思路
我一听,啊这,我只能想到页面加载完成后,找到对应需要的数据的dom元素中找出来数据,单独显示在界面某处,或者用弹窗的方式。至于手机上如何执行脚本嘛,那就用能运行脚本的浏览器,或者支持油猴的浏览器,例如via啥的。
开干
第一个坑
一开始,先从Chrome浏览器的console一行一行输入代码来获取dom,就是重复的var a = document.getElementById(’xxx’),一路下来还挺顺利的。很快,我便实现了在Console中加入一个Button,添加点击时间,并进行所需数据的排序和整理。
很快我变将其加入到油猴脚本中测试。
var newDiv = document.createElement("div");
newDiv.innerHTML='<button id="sort_button" onClick="doSort">排序</button>';
document.getElementById("div_search").appendChild(newDiv);
不行了,Button根本没出来。
原来,罪魁祸首就是这个iframe。
在油猴脚本中@match匹配的域名,和iframe中src的域名不同,那自然是获取不到dom的。
网上有说如何获取iframe中dom的方案,我尝试了一些,发现并不太好使,于是乎我的解决方案是,直接将@match写iframe对应的域名,终于看到了按钮了。
第二个坑
点击按钮,doSort not define。
好家伙,我明明定义了function doSort的啊。
尝试改成addEventListener后,有效果。
document.getElementById("sort_button").addEventListener("click", myFunction, false);
第三个坑
我起初偷懒,想直接将信息通过弹窗的方式,展示,每次需要看就弹窗一下。
可是,弹不出来,于是我尝试用console.log,居然也不出来的。
查看stackoverflow是这么说的。我也不知道有没有效果,但是最后也没有用alert,直接写了一个li标签。
console.log override not working in Tampermonkey
部署
一开始,我想到的是VIA浏览器可以执行脚本,但是我并没有去了解他的机制是否有区别,反正就是没有任何效果。
后来发现了一款可以安装插件的基于chromium的手机浏览器叫做Kiwi。(一直不知道为什么Chrome要在安卓端阉割掉这些)。
代码
// ==UserScript==
// @name xxx
// @namespace http://tampermonkey.net/
// @version 2024-02-17
// @description xxx
// @author xxx
// @match https://xxx.xxx.cn/*
// @icon xxx
// @grant none
// ==/UserScript==
(function() {
'use strict';
var newArray;
function doSort() {
newArray = Array();
var panners = document.getElementsByClassName('信息卡片的class,一共有16个');
for (var i = 0; i < panners.length; i++) {
var id = panners[i].id;
var lastIndex = id.lastIndexOf('-');
var shotId = id.substring(lastIndex + 1, lastIndex + 4);
var childDiv = panners[i].firstChild;
var mainDataDiv = childDiv.lastChild;
var detailDataDiv = mainDataDiv.lastChild;
var usefulData = detailDataDiv.firstChild;
var usefulDatas = usefulData.childNodes;
var use1DataNodes = usefulDatas[1].firstChild.childNodes;
var percent = use1DataNodes[3].lastChild.firstChild.innerText;
var use2DataNodes = usefulDatas[2].firstChild.childNodes;
var carNumber = use2DataNodes[0].lastChild.firstChild.innerText;
var carID = use2DataNodes[3].lastChild.firstChild.innerText;
var percentNum = 0;
if (percent !== '--') {
percentNum = Number(percent.substring(0, percent.length - 1));
}
var obj = {"shotId": shotId, "percent": percent, "carNumber": carNumber, "carID": carID, "percentNum": percentNum};
newArray.push(obj);
}
newArray = newArray.sort(function(a, b) {
if (a.percentNum === b.percentNum) {
return Number(a.shotId) - Number(b.shotId);
} else {
return b.percentNum - a.percentNum;
}
});
var sort_list = document.getElementById('sort_list');
var sort_list_html = '';
newArray.map(function(e, i){
sort_list_html = sort_list_html + '<li>' + e.shotId + ' ' + e.percent + ' ' + e.carNumber + ' ' + e.carID + '</li>';
});
sort_list.innerHTML = sort_list_html;
}
// 添加排序按钮
var newDiv = document.createElement("div");
newDiv.innerHTML='<button id="sort_button">排序</button>';
document.getElementById("div_search").appendChild(newDiv);
document.getElementById("sort_button").addEventListener("click", doSort, false);
// 添加排序列表
var newListDiv = document.createElement('div');
newListDiv.innerHTML='<ol id="sort_list"><li>Coffee</li><li>Milk</li>';
document.getElementById("div_search").appendChild(newListDiv);
})();
总结
也算是实现了这个小小的需求吧,不只是闷头干代码,还需要了解的是,油猴的沙盒机制,不然没有办法自动化执行。