【发布时间】:2015-08-30 08:38:12
【问题描述】:
(这是this discussion的延续)
我一直在尝试制作一个脚本(用于 instagram),以显示在查看个人资料页面 (example profile) 时当前共有多少张图片可见。它在屏幕右上角显示计数器并支持无限滚动。
这里是:
// ==UserScript==
// @name Instagram - visible images counter
// @name Instagram - visible images counter
// @include https://instagram.com/*
// @grant none
// ==/UserScript==
var p = document.getElementsByClassName('-cx-PRIVATE-PostsGridItem__root');
var m = document.getElementsByClassName('-cx-PRIVATE-PostsStatistic__count');
var ww = m[0].innerHTML.replace(/(\d+),(?=\d{3}(\D|$))/g, "$1"); // Regex to strip the thousand comma seperator from the posts number
var z = (p.length/ww)*100;
var counter = p.length+' / '+m[0].innerHTML +' that is ' +z.toFixed(1) + '%';
var div = document.createElement("div");
div.style.top = "1px";
div.style.right = "1px";
div.style.position = "fixed";
document.body.appendChild(div);
div.id="mycounter";
mycounter = document.getElementById('mycounter');
mycounter.innerHTML = counter;
mycounter.style.top = "1px";
mycounter.style.right = "1px";
mycounter.style.position = "fixed";
/// ---------------------------------
/// mutation observer -monitors the Posts grid for infinite scrolling event-
/// ---------------------------------
var target1 = document.querySelector('.-cx-PRIVATE-PostsGrid__root');
var observer1 = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
p=document.getElementsByClassName('-cx-PRIVATE-PostsGridItem__root');
m = document.getElementsByClassName('-cx-PRIVATE-PostsStatistic__count');
ww = m[0].innerHTML.replace(/(\d+),(?=\d{3}(\D|$))/g, "$1");
z = (p.length/ww)*100;
counter = p.length+' / '+m[0].innerHTML +' that is ' +z.toFixed(1) + '%';
mycounter.innerHTML = counter;
});
})
var config = { attributes: true, childList: true, characterData: true }
observer1.observe(target1, config);
我的脚本工作正常,但我遇到了这个问题:
Instagram,在最近重新设计后 - 我认为 - 似乎使用单页应用程序工作流程,
即获取点击的链接内容并用它替换当前页面,然后更改浏览器的当前 URL,所有这些都没有实际重新加载页面。
因此,我的脚本仅在我在新标签页中打开个人资料 URL 时才有效。
在打开个人资料 URL 时它不起作用在同一个标签中,而在我的时间线中 (https://instagram.com))。
换句话说,它不起作用(在我打开https://instagram.com 并登录后)
如果我点击查看我关注的用户的个人资料 URL,例如。 https://instagram.com/instagram/
我该如何解决这个问题?
Someone 提出了以下三种方式:
- 尝试使用
event handler处理 Instagram 网站触发的某些事件,例如 例如,github 上的pjax:end。- 使用
mutation observer等待特定于配置文件的 html 元素。- 或者使用
setInterval定期检查location.href。*
所以,我一直在尝试各种方法(包括建议 #2 和 #3),但没有成功。
(关于建议 #1:我找不到任何类似于 pjax:end 的元素)。
所以,到目前为止我所尝试的:
-
(基于建议 #2)添加另一个
mutation observer以检查显示“帖子计数”元素的元素是否存在,如果存在,则运行我的代码。var target0 = document.querySelector('.-cx-PRIVATE-PostsStatistic__count'); var observer0 = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { myCode(); }); }) var config0 = { attributes: true, childList: true, characterData: true } observer0.observe(target0, config0);
-
(基于建议#3)每1秒检查一次
location.href当前位置是否是配置文件(即不是时间线(https://instagram.com/)。如果为真则清除周期函数并运行我之前的代码。var interval = setInterval(testHref() , 1000); function testHref(){ if (location.href != "https://instagram.com/") clearInterval(interval); myCode(); }
-
只需在我的代码顶部添加 1 秒延迟(并将 @require 规则更改为仅适用于配置文件 URL
// @include https://instagram.com/*/),但没有成功:setTimeout(function() { }, 1000);
-
我什至尝试过使用 waitForKeyElements 实用程序函数,它可以检测和处理 AJAX 化内容。
我认为以这种方式实现起来要容易得多,就像一个简单的“等到一个元素存在”一样工作(我只是使用主配置文件图片作为等待的选择器,因为我找不到任何相关的 AJAX 选择器。我也没有'不要在我的代码中使用 jNode)。
所以我只是将我的整个代码包含在一个函数visibleCounter中,并添加了一个 waitForKeyElements 行(见下文),但不幸的是它也不起作用:waitForKeyElements (".-cx-PRIVATE-ProfilePage__avatar", visibleCounter); function visibleCounter(jNode){ myCode() }
【问题讨论】:
-
如果选项 1 和 3 对您来说太高级,您应该花时间学习它们,以免它们看起来不高级。事件处理是 JS 脚本的基础。
-
我总是尝试提高我对 javascript 的了解(无论是在线文档、书籍、stackexchange 网站等)。事件处理对我来说不再那么先进了——只是似乎没有任何效果,尽管我尝试过。
标签: javascript greasemonkey instagram html5-history