如何检测页面是否已更新其内容?
How to detect if a page has updated its content?
我正在制作一个 javascript 代码,现在在控制台中使用它,但也许我稍后会把它变成一个扩展,它会在这个列表中的每个 Facebook 好友旁边创建一个复选框:[https://mobile.facebook.com/[Your Username]/friends]
首先脚本需要向下滚动直到加载所有朋友,然后附加复选框。问题是我无法告诉脚本何时停止滚动,唯一的方法是检测页面是否已更新,我不知道该怎么做?
我试过的
第一种方法
我的第一个想法是让用户可以选择加载多少好友,然后加载好友,直到输入的数量小于加载的好友数量
x = parseInt(prompt("How many friends you wanna load?"))
friends = document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]')
scrolling = (n) => {
if(x < 0 || x > 5000) return console.log("invalide number");
console.log(n + " friends loaded")
if(n < x) {
setTimeout(function() {
window.scrollTo(0, 9999999);
friends = document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]');
scrolling(friends.length)
}, 3000)
}
else
{
// create_checkboxes();
}
}
scrolling(friends.length)
这种方法的问题是:用户可能会给出一个不合理的数字,比如他有500个朋友,而作为输入他想加载600个朋友,这将是一个无限循环,因为数字friends.length
永远不会大于输入。而且脚本无法获取用户有多少好友。
第二种方法
我想过指定迭代次数,根据我的计算,139次迭代足以加载5000个朋友,但这有两个问题:
第一个很清楚,对于那些朋友很少的人来说,这将是浪费时间。
第二个,如果互联网很慢,可能在等待 3 秒后(检查 setTimeOut)朋友将不会被加载,因此甚至 139 次迭代也可能不够,脚本也不知道。
所以我唯一的希望是一种检测 Facebook 是否进行了更改并加载更多朋友的方法,也许是一种检测 dom 是否已更改的方法,甚至是一种检测页面是否已更改的方法到达页面底部后没有生成 XHR,后一种方法不太好,因为它可能只是因为网速慢。
您可以查看加载朋友的 div 的高度。并继续向下滚动。在高度停止变化之前,您应该知道所有朋友都已加载并且没有其他内容 load.Or 您可以将帐户有多少朋友存储在变量中并检查有多少朋友 div'在那里。如果好友 div 的计数达到好友计数,您就可以开始了。
在列表的底部,Facebook 维护了一个 div 和 class seeMoreFriends
,只有当有更多朋友加载时才会出现:
<div class="seeMoreFriends acw apl" id="m_more_friends" data-sigil="marea">
<div style="text-align:center;" class="centeredIndicator">
<div class="_2so _2sq _2ss img _50cg" data-animtype="1" id="u_6_11" data-sigil="m-loading-indicator-animate m-loading-indicator-root"></div>
</div>
</div>
利用这个信息,你可以检查这个div是否存在,如果存在,你就知道你可以继续滚动,否则,你可以停止滚动。使用 MutationObserver
您将知道何时为每个新负载检查上述 div 是否存在:
const callback = (mutationList, observer) => {
const moreFriends = document.querySelector(".seeMoreFriends");
if (moreFriends) {
moreFriends.scrollIntoView();
} else {
observer.disconnect();
addCheckboxs();
}
}
const addCheckboxs = () => {
document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]').forEach(item => {
item.insertAdjacentHTML('beforebegin', '<input type="checkbox">')
});
}
window.addEventListener("load", () => { // If running in the console the page would have already been loaded, so you can run the callback code directly
const loader = document.querySelector(".seeMoreFriends");
if (loader) { // if more friends to load
const obs = new MutationObserver(callback);
obs.observe(document.querySelector("._2pit"), {
childList: true
}); // listen to changes on the container div of the friends list (holding the seeMoreFriends div and friends list divs)
loader.scrollIntoView(); // kick off the loading, which will then trigger the mutation observer callback as the page continues to laod
} else {
addCheckboxs();
}
});
我正在制作一个 javascript 代码,现在在控制台中使用它,但也许我稍后会把它变成一个扩展,它会在这个列表中的每个 Facebook 好友旁边创建一个复选框:[https://mobile.facebook.com/[Your Username]/friends]
首先脚本需要向下滚动直到加载所有朋友,然后附加复选框。问题是我无法告诉脚本何时停止滚动,唯一的方法是检测页面是否已更新,我不知道该怎么做?
我试过的
第一种方法
我的第一个想法是让用户可以选择加载多少好友,然后加载好友,直到输入的数量小于加载的好友数量
x = parseInt(prompt("How many friends you wanna load?"))
friends = document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]')
scrolling = (n) => {
if(x < 0 || x > 5000) return console.log("invalide number");
console.log(n + " friends loaded")
if(n < x) {
setTimeout(function() {
window.scrollTo(0, 9999999);
friends = document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]');
scrolling(friends.length)
}, 3000)
}
else
{
// create_checkboxes();
}
}
scrolling(friends.length)
这种方法的问题是:用户可能会给出一个不合理的数字,比如他有500个朋友,而作为输入他想加载600个朋友,这将是一个无限循环,因为数字friends.length
永远不会大于输入。而且脚本无法获取用户有多少好友。
第二种方法
我想过指定迭代次数,根据我的计算,139次迭代足以加载5000个朋友,但这有两个问题: 第一个很清楚,对于那些朋友很少的人来说,这将是浪费时间。 第二个,如果互联网很慢,可能在等待 3 秒后(检查 setTimeOut)朋友将不会被加载,因此甚至 139 次迭代也可能不够,脚本也不知道。
所以我唯一的希望是一种检测 Facebook 是否进行了更改并加载更多朋友的方法,也许是一种检测 dom 是否已更改的方法,甚至是一种检测页面是否已更改的方法到达页面底部后没有生成 XHR,后一种方法不太好,因为它可能只是因为网速慢。
您可以查看加载朋友的 div 的高度。并继续向下滚动。在高度停止变化之前,您应该知道所有朋友都已加载并且没有其他内容 load.Or 您可以将帐户有多少朋友存储在变量中并检查有多少朋友 div'在那里。如果好友 div 的计数达到好友计数,您就可以开始了。
在列表的底部,Facebook 维护了一个 div 和 class seeMoreFriends
,只有当有更多朋友加载时才会出现:
<div class="seeMoreFriends acw apl" id="m_more_friends" data-sigil="marea">
<div style="text-align:center;" class="centeredIndicator">
<div class="_2so _2sq _2ss img _50cg" data-animtype="1" id="u_6_11" data-sigil="m-loading-indicator-animate m-loading-indicator-root"></div>
</div>
</div>
利用这个信息,你可以检查这个div是否存在,如果存在,你就知道你可以继续滚动,否则,你可以停止滚动。使用 MutationObserver
您将知道何时为每个新负载检查上述 div 是否存在:
const callback = (mutationList, observer) => {
const moreFriends = document.querySelector(".seeMoreFriends");
if (moreFriends) {
moreFriends.scrollIntoView();
} else {
observer.disconnect();
addCheckboxs();
}
}
const addCheckboxs = () => {
document.querySelectorAll('._55wp._7om2._5pxa._8yo0[data-sigil="undoable-action"]').forEach(item => {
item.insertAdjacentHTML('beforebegin', '<input type="checkbox">')
});
}
window.addEventListener("load", () => { // If running in the console the page would have already been loaded, so you can run the callback code directly
const loader = document.querySelector(".seeMoreFriends");
if (loader) { // if more friends to load
const obs = new MutationObserver(callback);
obs.observe(document.querySelector("._2pit"), {
childList: true
}); // listen to changes on the container div of the friends list (holding the seeMoreFriends div and friends list divs)
loader.scrollIntoView(); // kick off the loading, which will then trigger the mutation observer callback as the page continues to laod
} else {
addCheckboxs();
}
});