如何在Twitter对话中的每个无限滚动事件上执行Greasemonkey脚本

How to execute a Greasemonkey script on every infinite scrolling event in a Twitter conversation?

本文关键字:事件 滚动 无限 执行 脚本 Greasemonkey Twitter 对话      更新时间:2023-09-26

我正在尝试制作一个可以在Twitter对话
中使用的油脂猴用户脚本(着色名称,用户名和每个第一@reply)。

当Twitter对话有很多回复(示例链接)时,
然后打开这样的链接只显示 3 个屏幕的回复(初始屏幕 + 2 更多)
-至少在我的1920x1200显示器中-然后,您必须手动向下滚动才能看到其余的回复。

如何使脚本在每个无限滚动事件上执行(每次Mousewheel downPgDnDown arrow ↓按键)?

有人好心地建议:

尝试在 FF devtools 调试器中检查代码(右键单击代码 并选择"美化来源")以查看infiniteScrollWatcher情况 引发

所以,我想我应该使用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请求添加全局成功处理程序的选项,您可以使用此处理程序。

在处理程序内部:

  1. 解析当前 URL 以获取用户名和对话 ID
  2. 根据上面的路径测试 AJAX 请求的 URL(将用户名和会话 ID 替换为步骤 #1 中的结果)
  3. 检查响应是否包含包含非空格字符的属性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);