13

我一直在对 Twitter 的嵌入式时间线进行大量研究。我一直在试图弄清楚是否有可能知道时间线何时完成加载并显示在页面上。已请求此问题,但尚未实施。我走到了死胡同,希望有人能够帮助我找到解决方案。这是我到目前为止发现的:

添加嵌入式时间轴的代码:

<a class="twitter-timeline" href="https://twitter.com/twitterapi" data-widget-id="YOUR-    WIDGET-ID-HERE">Tweets by @twitterapi</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

运行脚本时会发生什么:

  1. 该脚本将<a>标签替换为一个<iframe>元素。

  2. 内容iframe已准备就绪,但头像图像和“关注@username”按钮尚未完成下载。的属性设置为 0,这样您就看不到没有图像的内容iframeheight

  3. 头像图片已下载,但“关注@username”按钮仍在下载中。内容仍然不可见。

  4. “关注@username”按钮已完成下载。的属性被设置为匹配iframeheight内容的高度iframe。时间线现在可见。

现在,我已经尝试了我能想到的一切来确定时间线何时可见(使用 settimeout/interval)。目标是有一个非轮询事件/函数/回调。这是我迄今为止尝试过的但没有成功的方法:

  • iframe在(例如onloadDOMContentLoaded、等)上设置事件侦听DOMFrameContentLoaded器以了解内容何时完成加载。这不起作用,因为iframe没有src属性。在浏览了 uglified 代码之后(我找不到未压缩的版本),我的猜测是它正在使用 writes 将内容添加到iframe.
  • 设置事件侦听器以height了解iframe. 从理论上讲,这个事件应该触发三次:第一次是在内容加载时,第二次height是在设置为 0 时,第三次height是在设置为显示完全加载的时间线时。但是,我只能在前两种情况下触发事件,而在第三种情况下(我真正想要的情况)永远不会触发。我使用DOMSubtreeModified,onreadystatechangeonpropertychange, 但仅DOMSubtreeModified用于触发事件。
  • iframe. 因为 JavaScript 可以从 Twitter 到达内部iframe,所以可以抓取内部的任何元素iframe(例如documentwindow)。但是,在或上添加onloadDOMContentLoadedDOMFrameContentLoaded事件侦听器仍然不会触发这些事件。windowdocumentiframe
  • 在“关注@username”按钮上设置事件监听器。该按钮实际上是一个iframe具有src属性的按钮。通过设置一个onload事件,它会在加载时被触发。但是,该onload事件总是会触发两次。第一次完成下载,第二次完成处理。在第二次触发之后,将立即显示时间线。但是,要实现这一点很麻烦(我想一切都是),因为您必须等待iframe加载的内容,到达内部并获取 'follow @username' iframe,在其上设置一个onload事件,然后等待第二个事件火。
  • 使用该twttr.widgets.createTimeline()函数,该函数具有用于回调的可选参数。但是,当内容准备好(第 2 步)时调用回调,而不是当 iframe 可见时(第 4 步)。

在这一点上我可能忘记了更多的组合。我知道存在一个使用 Twitter的github gistwidget.js,但添加了回调。我无法让它工作。

很抱歉日志问题,但我希望有人能够提供帮助。谢谢。

4

3 回答 3

11

即使已经过去了 1 个月,我也会在这里发布我的解决方案,以防万一有人再次找到这篇文章,我要做的就是轮询直到 iframe 的宽度 > 1 作为回调的指标

if ($('.twitter-timeline').length) {
    //Timeline exists is it rendered ?
    interval_timeline = false;
    interval_timeline = setInterval(function(){
        console.log($('.twitter-timeline').width());
        if ($('.twitter-timeline').hasClass('twitter-timeline-rendered')) {
            if ($('.twitter-timeline').width() > 10) {
                //Callback
                clearInterval(interval_timeline);
                DoWhatEverYouNeedHere();
            }     
        }
    },200);
}
于 2013-08-22T20:54:28.913 回答
10

当您复制并粘贴从 Twitter 获得的代码时,您必须替换它:

<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

有了这个:

<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";js.setAttribute('onload', "twttr.events.bind('rendered',function(e) {doSomething()});");fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>

当然,上面调用的 doSomething 函数是在嵌入时间线加载和渲染时运行的回调。

另外,我猜这个解决方案在 Internet Explorer 中不起作用,因为它不支持脚本元素的 onLoad 事件。然而,有解决方案

最后,您可以在我编写的 Twitter 嵌入式时间线抓取工具中看到我解决此问题的方法。

于 2014-02-27T19:18:36.410 回答
3

您可以尝试使用 Javascript 工厂而不是属性绑定。createTimeline 方法返回一个承诺,因此您可以在此处链接您的加载后活动。请参阅 Twitter 文档:https ://dev.twitter.com/web/embedded-timelines/parameters

twttr.widgets.createTimeline(
    "YOUR-WIDGET-ID-HERE",
    document.getElementById("container"),
    {
        height: 400,
        chrome: "nofooter",
        linkColor: "#820bbb",
        borderColor: "#a80000"
    }
)
.then(function(){
      DoSomething();
});
于 2015-07-14T19:10:44.140 回答