【问题标题】:Twitter Embedded Timeline CallbackTwitter 嵌入式时间线回调
【发布时间】:2015-07-15 03:10:44
【问题描述】:

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

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

<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. 脚本将&lt;a&gt; 标记替换为&lt;iframe&gt; 元素。

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

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

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

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

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

此时我可能忘记了更多组合。我知道有一个 github gist 使用 Twitter widget.js,但添加了回调。我无法让它工作。

对不起,日志问题,但我希望有人能够提供帮助。谢谢。

【问题讨论】:

    标签: javascript twitter


    【解决方案1】:

    我会在这里发布我的解决方案,即使它已经过去了 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);
    }
    

    【讨论】:

    • 根据您要执行的操作,检查宽度可能不起作用,如果发生这种情况,请尝试检查高度值。我必须这样做才能让我的事情发挥作用。
    【解决方案2】:

    当您复制并粘贴从 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 事件。 Yet there are solutions for that.

    最后,您可以在the Twitter embedded timeline scraper I wrote 中查看我解决此问题的方法。

    【讨论】:

    • 这个刮刀是如何工作的?我看了看,您正在通过脚本从另一个域访问 IFrame 的内容,这会导致安全错误。这是一个很酷的想法,我只是想知道你是否做了一些额外的事情来解决这个问题。
    • @Andy ,爬虫不会尝试从另一个域访问 IFrame。 Twitter 小部件包含一个动态创建 IFrame 的脚本,但它不会直接从另一个域加载它,因此当您尝试抓取它时不会遇到任何安全错误。
    • 我不知道twttr.events.bind。它似乎也在正确的时间开火。对于想知道哪些事件是可绑定的其他人,您可以在此处找到有关所有事件的信息:dev.twitter.com/docs/tfw/events。此外,只有 IE8 及以下版本不支持脚本的 onload 事件。 IE9+ 可以(见pieisgood.org/test/script-link-events)。
    【解决方案3】:

    您可以尝试使用 Javascript 工厂而不是属性绑定。 createTimeline 方法返回一个承诺,因此您可以在此处链接您的加载后活动。 查看推特文档: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();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2013-06-12
      相关资源
      最近更新 更多