我目前正在为一个提供在线观看系列的网站构建一个UserScript / Greasemonkey脚本。他们有一个按字母顺序列出所有系列的页面,并且几乎每天都会添加新系列。这是一个包含<li>
元素的无序列表。
所以,问题是,那些<li>
元素没有id,只有里面的链接像“/ series / scrubs”。因此,我希望用户单击我已使用UserScript添加的眼睛图标,然后使用<li>
标记包含该图标的background-color: green;
条目。
此外,我想存储这些标记并在每次脚本加载时恢复它们,可能使用GM_setValue
和GM_getValue
。
我的问题是,如何使用Greasemonkey保存变量,让我们说GM_setValue("series/Scrubs", 1);
其中“series / Scrubs”代表链接的href?如何在脚本加载中恢复标记为<li>
的条目?
如上所述,我没有任何ID可供使用,我不能使用<li>
- 条目1,条目2等,因为列表将被破坏,因为几乎每天都有新的{{在其他人之间等等。
TL; DR,一些代码让你们明白:
<li>
以下是我已有的代码,添加眼睛图标等等。
<ul id='serSeries'>
<li><a href="serie/hack-Legend-of-the-Twilight">.hack//Legend of the Twilight</a></li>
<li><a href="serie/hack-Roots">.hack//Roots</a></li>
<li><a href="serie/hack-Sign">.hack//Sign</a></li>
<li><a href="serie/07-Ghost">07-Ghost</a></li>
<li><a href="serie/10-Dinge-die-ich-an-dir-hasse">10 Dinge, die ich an dir hasse</a></li>
<li><a href="serie/10-8-Officers-on-Duty">10-8: Officers on Duty</a></li>
<li><a href="serie/1000-Wege-ins-Gras-zu-beissen">1000 Wege, ins Gras zu beißen</a></li>
<li><a href="serie/101-Dalmatiner">101 Dalmatiner</a></li>
哦,是的,我的函数if (!this.GM_getValue || (this.GM_getValue.toString && this.GM_getValue.toString().indexOf("not supported")>-1)) {
this.GM_getValue=function (key,def) {
return localStorage[key] || def;
};
this.GM_setValue=function (key,value) {
return localStorage[key]=value;
};
this.GM_deleteValue=function (key) {
return delete localStorage[key];
};
}
function countSeries(){
return document.getElementById("serSeries").getElementsByTagName("li").length;
}
function mark(id){
var se = countSeries()-1;
for(var i=0; i < se; i++){
if(i == id){
var serie = document.getElementById("serSeries").getElementsByTagName("li")[i].getElementsByTagName("a")[0].getAttribute("href");
GM_setValue(serie, "1");
document.getElementById("serSeries").getElementsByTagName("li")[i].backgroundColor = "green";
}
}
}
function appendViewStateOnAll() {
var se = countSeries()-1;
for(var i=0; i < se; i++){
var link = document.createElement("a");
link.innerHTML = "<a onclick='javascript:mark(" + i + ")' href='javascript:void(0);'> <img src='http://i.epvpimg.com/2gpcf.png'></a>";
link.id = i;
document.getElementById("serSeries").getElementsByTagName("li")[i].getElementsByTagName("a")[0].appendChild(link);
}
}
appendViewStateOnAll();
无效。
提前致谢。
答案 0 :(得分:0)
你的问题令人困惑,但我会花点时间推断一下我认为问题的意图。 (不,我没有读过你的代码,它是TL; DR)。
假设一个人无法控制列表标记,则必须在每个页面加载时重新创建标记。这也意味着您必须在Greesemonkey中管理页面标记与列表数据的内部表示之间的差异。
要做的第一件事是定义如何解决three-way merge的规则。例如,如果您的注入包含项目(C)
在两个集合列表中(a, C, b)
并且新刷新添加(d)
项目,您如何确定应注入(C)
的位置: (a, d, C, b)
或(a, C, d, b)
或(a, C, b, d)
等。这些规则是唯一可以帮助您的规则。
其次,您必须开发一个数据模型来表示此列表,该列表兼容在一些持久存储机制中保存到Greesemonkey。
最后,在每次重新加载页面时,您必须构建列表的表示,执行三向合并算法,然后用新合并的列表替换列表。
所有这些都是非常先进的东西。更大的问题以及我无法进一步扩展这个答案的原因(因此我在这个答案中缺少代码示例)是你没有规定你希望它如何工作/看起来像。我认为你需要考虑一下你希望列表的修改最终看起来如何,并在寻找解决方案之前明确说明。
同样,我没有阅读您的代码实现。您可能已经考虑过这一点并尝试通过代码传达规范。但是对于一个SO问题我(也不是,我怀疑,许多其他读者)会花时间通过代码来解密它。
答案 1 :(得分:0)
// ==UserScript==
// @name test
// @namespace http://stackoverflow.com
// @version 1.0
// @description http://stackoverflow.com/questions/25664703/how-can-i-persist-greasemonkey-changes-to-a-ul-without-any-ids-which-is-getti
// @include http://fiddle.jshell.net/*
// @author zanetu
// @grant GM_addStyle
// ==/UserScript==
function toggle(event) {
var previous = event.target.previousSibling;
var key = previous.getAttribute('href');
if(localStorage.getItem(key)) {
localStorage.removeItem(key);
previous.style.backgroundColor = '';
}
else {
localStorage.setItem(key, '1');
previous.style.backgroundColor = 'green';
}
}
function appendViewStateOnAll() {
var links = document.querySelectorAll('#serSeries > li > a[href^="serie/"]');
for(var i = links.length - 1; i > -1; i--) {
var image = document.createElement('img');
image.src = 'http://i.epvpimg.com/2gpcf.png';
image.style.cursor = 'pointer';
image.addEventListener('click', toggle, false);
//may not work with internet explorer
links[i].parentNode.insertBefore(image, links[i].nextSibling);
//restore background color
if(localStorage.getItem(links[i].getAttribute('href'))) {
links[i].style.backgroundColor = 'green';
}
}
}
appendViewStateOnAll();