如何在 Twitter 对话中的每个无限滚动事件上执行 Greasemonkey 脚本?
How to execute a Greasemonkey script on every infinite scrolling event in a Twitter conversation?
我正在尝试制作一个可以在 Twitter 对话中使用的 greasemonkey 用户脚本
(为名称、用户名和每个第一个@reply 着色)。
当 Twitter 对话有很多回复时 (example link),
然后打开这样一个 link 只显示 3 屏的回复(初始屏幕 + 2 更多)
-至少在我的 1920x1200 显示器中-
然后你必须手动向下滚动才能看到其余的回复。
如何让我的脚本在每个无限滚动事件上执行
(在每个 Mousewheel down
或 PgDn
或 Down arrow ↓
按键上)?
有人好心建议:
Try inspecting the code in FF devtools debugger (right click the code
and choose 'prettify source') to see how infiniteScrollWatcher
is
triggered
所以,我想我应该使用以下方法将事件侦听器绑定到此函数
EventTarget.addEventListener,
但我不知道怎么做(这个功能对我来说太高级了).
该函数的美化源是:
function infiniteScrollWatcher() {
var a = 0,
b = 1;
this.checkScrollPosition = function () {
var c = this.webkitFullscreenElement();
if (c && this.node != c && !c.contains(this.node)) return;
var d = this.$content.height(),
e = !1;
this.inTriggerRange(a) && (d > this.lastTriggeredHeight || this.lastTriggeredFrom(b)) ? (this.trigger('uiNearTheTop'), this.lastTriggerFrom = a, e = !0) : this.inTriggerRange(b) && (d > this.lastTriggeredHeight || this.lastTriggeredFrom(a)) && (this.trigger('uiNearTheBottom'), this.lastTriggerFrom = b, e = !0),
e && (this.lastTriggeredHeight = d)
},
this.inTriggerRange = function (c) {
var d = this.$content.height(),
e = this.$node.scrollTop(),
f = e + this.$node.height(),
g = Math.abs(Math.min(f - d, 0)),
h = this.$node.height() / 2;
return e < h && c == a || g < h && c == b
},
this.lastTriggeredFrom = function (a) {
return this.lastTriggerFrom === a
},
this.resetScrollState = function () {
this.lastTriggeredHeight = 0,
this.lastTriggerFrom = - 1
},
this.webkitFullscreenElement = function () {
return document.webkitFullscreenElement
},
this.after('initialize', function () {
this.resetScrollState(),
this.$content = this.attr.contentSelector ? this.select('contentSelector') : $(document),
this.on('scroll', utils.throttle(this.checkScrollPosition.bind(this), 100)),
this.on('uiTimelineReset', this.resetScrollState),
this.on('uiSwiftLoaded uiPageChanged', this.checkScrollPosition)
})
}
不同的方法:
Twitter 通过 jQuery 发送获取结果的请求,路径为:
/twitter.com/i/[username]/conversation/[conversationid]?[query]
jQuery 包含向所有 ajax 请求添加全局成功处理程序的选项,您可以使用此处理程序。
处理程序内部:
- 解析当前 url 以获取用户名和对话 ID
- 根据上述路径测试 AJAX 请求的 url(将用户名和对话 ID 替换为步骤#1 的结果)
- 检查响应是否包含 属性
items_html
其中包括非空白字符
当第 2 步和第 3 步成功时,新项目已加载,执行您想要的指令。
样本:
// ==UserScript==
// @name twitter
// @namespace twitter
// @include https://twitter.com/*
// @version 1
// @grant none
// ==/UserScript==
window.addEventListener('load', function() {
var path=location.pathname.split(/\//,5),_url;
//check if we're inside a conversation
if(path.length>=4 && path[2]==='status' && !isNaN(path[3])){
//create the path for the comparison
_url='/'+['i',path[1],'conversation',path[3]].join('/')+'?';
$(document).ajaxSuccess(function(a, b, opts, data) {
if (opts.url.indexOf(_url) === 0 //urls match
&&
data.items_html
&&
data.items_html.match(/\S/)//new items availabe
) {
//do what you want to
alert('new content inserted');
}
});
}
},
false);
但是当您只想应用自定义样式时,您不需要关心新内容,只需将带有一些自定义规则的样式表添加到文档中即可(也可以通过 Stylish 完成) :
// ==UserScript==
// @name twitter
// @namespace twitter
// @include https://twitter.com/*
// @version 2
// @grant none
// ==/UserScript==
var style=document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(style);
//name
style.sheet.insertRule('.tweet .stream-item-header strong.fullname' +
'{background:tomato;color:white}',0);
//username
style.sheet.insertRule('.tweet .stream-item-header span.username' +
'{background:tomato;color:black}',0);
//first @reply
style.sheet.insertRule('.tweet .tweet-text a.twitter-atreply:first-of-type *' +
'{background:blue;color:orange !important;}',0);
我正在尝试制作一个可以在 Twitter 对话中使用的 greasemonkey 用户脚本
(为名称、用户名和每个第一个@reply 着色)。
当 Twitter 对话有很多回复时 (example link),
然后打开这样一个 link 只显示 3 屏的回复(初始屏幕 + 2 更多)
-至少在我的 1920x1200 显示器中-
然后你必须手动向下滚动才能看到其余的回复。
如何让我的脚本在每个无限滚动事件上执行
(在每个 Mousewheel down
或 PgDn
或 Down arrow ↓
按键上)?
有人好心建议:
Try inspecting the code in FF devtools debugger (right click the code and choose 'prettify source') to see how
infiniteScrollWatcher
is triggered
所以,我想我应该使用以下方法将事件侦听器绑定到此函数 EventTarget.addEventListener, 但我不知道怎么做(这个功能对我来说太高级了).
该函数的美化源是:
function infiniteScrollWatcher() {
var a = 0,
b = 1;
this.checkScrollPosition = function () {
var c = this.webkitFullscreenElement();
if (c && this.node != c && !c.contains(this.node)) return;
var d = this.$content.height(),
e = !1;
this.inTriggerRange(a) && (d > this.lastTriggeredHeight || this.lastTriggeredFrom(b)) ? (this.trigger('uiNearTheTop'), this.lastTriggerFrom = a, e = !0) : this.inTriggerRange(b) && (d > this.lastTriggeredHeight || this.lastTriggeredFrom(a)) && (this.trigger('uiNearTheBottom'), this.lastTriggerFrom = b, e = !0),
e && (this.lastTriggeredHeight = d)
},
this.inTriggerRange = function (c) {
var d = this.$content.height(),
e = this.$node.scrollTop(),
f = e + this.$node.height(),
g = Math.abs(Math.min(f - d, 0)),
h = this.$node.height() / 2;
return e < h && c == a || g < h && c == b
},
this.lastTriggeredFrom = function (a) {
return this.lastTriggerFrom === a
},
this.resetScrollState = function () {
this.lastTriggeredHeight = 0,
this.lastTriggerFrom = - 1
},
this.webkitFullscreenElement = function () {
return document.webkitFullscreenElement
},
this.after('initialize', function () {
this.resetScrollState(),
this.$content = this.attr.contentSelector ? this.select('contentSelector') : $(document),
this.on('scroll', utils.throttle(this.checkScrollPosition.bind(this), 100)),
this.on('uiTimelineReset', this.resetScrollState),
this.on('uiSwiftLoaded uiPageChanged', this.checkScrollPosition)
})
}
不同的方法:
Twitter 通过 jQuery 发送获取结果的请求,路径为:
/twitter.com/i/[username]/conversation/[conversationid]?[query]
jQuery 包含向所有 ajax 请求添加全局成功处理程序的选项,您可以使用此处理程序。
处理程序内部:
- 解析当前 url 以获取用户名和对话 ID
- 根据上述路径测试 AJAX 请求的 url(将用户名和对话 ID 替换为步骤#1 的结果)
- 检查响应是否包含 属性
items_html
其中包括非空白字符
当第 2 步和第 3 步成功时,新项目已加载,执行您想要的指令。
样本:
// ==UserScript==
// @name twitter
// @namespace twitter
// @include https://twitter.com/*
// @version 1
// @grant none
// ==/UserScript==
window.addEventListener('load', function() {
var path=location.pathname.split(/\//,5),_url;
//check if we're inside a conversation
if(path.length>=4 && path[2]==='status' && !isNaN(path[3])){
//create the path for the comparison
_url='/'+['i',path[1],'conversation',path[3]].join('/')+'?';
$(document).ajaxSuccess(function(a, b, opts, data) {
if (opts.url.indexOf(_url) === 0 //urls match
&&
data.items_html
&&
data.items_html.match(/\S/)//new items availabe
) {
//do what you want to
alert('new content inserted');
}
});
}
},
false);
但是当您只想应用自定义样式时,您不需要关心新内容,只需将带有一些自定义规则的样式表添加到文档中即可(也可以通过 Stylish 完成) :
// ==UserScript==
// @name twitter
// @namespace twitter
// @include https://twitter.com/*
// @version 2
// @grant none
// ==/UserScript==
var style=document.createElement('style');
document.getElementsByTagName('head')[0].appendChild(style);
//name
style.sheet.insertRule('.tweet .stream-item-header strong.fullname' +
'{background:tomato;color:white}',0);
//username
style.sheet.insertRule('.tweet .stream-item-header span.username' +
'{background:tomato;color:black}',0);
//first @reply
style.sheet.insertRule('.tweet .tweet-text a.twitter-atreply:first-of-type *' +
'{background:blue;color:orange !important;}',0);