问题描述
我一直在对 Twitter 的嵌入式时间线进行大量研究.我一直试图弄清楚是否有可能知道时间线何时完成加载并显示在页面上.此问题已被请求,但尚未实施.我走到了死胡同,希望有人能够帮助我找到解决方案.这是我目前发现的:
I've been doing a lot of research into Twitter's Embedded Timelines. I've been trying to figure out if it is possible to know when the timeline is finished loading and displays on the page. This issue has been requested, but has yet to be implemented. I have come to a dead end an am hoping someone is able to help me find the solution. Here is what I have found so far:
添加嵌入式时间轴的代码:
The code to add an Embedded Timeline:
<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>
运行脚本时会发生什么:
What happens when the script is run:
The script replaces the
<a>
tag with an<iframe>
element.
iframe
的内容已准备就绪,但头像和关注@username"按钮尚未下载.iframe
的 height
属性设置为 0,这样您就看不到没有图像的内容.
The contents of the iframe
are ready, but the avatar image and the 'follow @username' button are not done downloading. The iframe
's height
attribute is set to 0 so that you don't see the content without the images.
头像已下载,但关注@用户名"按钮仍在下载.内容仍然不可见.
The avatar image is downloaded, but the 'follow @username' button is still downloading. Content is still not visible.
'follow @username' 按钮下载完成.iframe
的 height
属性设置为匹配 iframe
的内容的高度.时间线现在可见.
The 'follow @username' button is finished downloading. The iframe
's height
attribute is set to match the height of the contents of the iframe
. The timeline is now visible.
现在,我已经尝试了所有我能想到的方法来确定时间线何时可见(没有使用 settimeout/interval).目标是有一个非轮询事件/函数/回调.这是我迄今为止尝试过但没有成功的方法:
Now, I've tried everything I can think of to figure out when the timeline is visible (without using settimeout/interval). The goal is to have a non-polling event/function/callback. Here is what I have tried so far without success:
- 在
iframe
(如onload
、DOMContentLoaded
、DOMFrameContentLoaded
等)上设置事件监听器来了解当内容加载完成时.这不起作用,因为iframe
没有src
属性.经过丑化的代码(我找不到未压缩的版本)后,我的猜测是它正在使用写入将内容添加到iframe
的正文中. - 设置事件侦听器以了解
iframe
上的height
属性何时发生变化.理论上,这个事件应该触发三次:第一次在内容加载时,第二次当height
设置为 0 时,第三次当height
设置为显示完全加载时时间线.但是,我只能在前两种情况下触发事件,而对于第三种情况(我真正想要的情况)却从未触发过.我使用了DOMSubtreeModified
、onreadystatechange
和onpropertychange
,但只有DOMSubtreeModified
用于触发事件. - 在
iframe
的内容上设置事件侦听器.因为 JavaScript 可以从 Twitter 到达iframe
内部,所以可以抓取iframe
内的任何元素(例如document
或窗口
).但是,在window
或document
上添加onload
、DOMContentLoaded
或DOMFrameContentLoaded
事件侦听器iframe
的 > 仍然不会触发这些事件. - 在follow @username"按钮上设置事件侦听器.该按钮实际上是一个
iframe
,它确实有一个src
属性.通过设置onload
事件,它会在加载时被触发.但是,onload
事件总是会触发两次.第一次下载完成,第二次处理完成.在第二次触发后,将立即显示时间线.不过,要实现这一点非常困难(我猜一切都是这样),因为您必须等待iframe
的内容加载,到达内部并获取跟随@username"iframe
,在其上设置一个onload
事件,然后等待第二个事件触发. - 使用
twttr.widgets.createTimeline()
函数,该函数具有用于回调的可选参数.但是,当内容准备好(第 2 步)时调用回调,而不是在 iframe 可见时(第 4 步)调用.
- Setting event listeners on the
iframe
(such asonload
,DOMContentLoaded
,DOMFrameContentLoaded
, etc) to know when the content has finished loading. This doens't work becuase theiframe
has nosrc
attribute. After going through the uglified code (I was unable to find an uncompressed version), my guess is that it is using writes to add the content to the body of theiframe
. - Setting event listeners to know when the
height
attribute changes on theiframe
. Theoretically, this event should fire three times: first when the content loads, second when theheight
is set to 0, and third when theheight
is set to show the fully loaded timeline. However, I was only able to get the event to fire for the first two cases and never for the third (the one I actually wanted). I usedDOMSubtreeModified
,onreadystatechange
, andonpropertychange
, but onlyDOMSubtreeModified
worked for firing the event. - Setting event listeners on the cotents of the
iframe
. Because JavaScript can reach inside of theiframe
from Twitter, it is possible to grab any element inside theiframe
(such asdocument
orwindow
). However, addingonload
,DOMContentLoaded
, orDOMFrameContentLoaded
event listeners on thewindow
ordocument
of theiframe
still does not fire those events. - Setting event listeners on the 'follow @username' button. The button is actually an
iframe
that does have asrc
attribute. By setting anonload
event, it will get fired when it is loaded. However, theonload
event will always fire twice. The first time when it has finished downloading and the second when it has finished processing. Immediatly after the second trigger, the timeline will be shown. To implement this is quite the hack though (I guess everything is) since you must wait for the contents of theiframe
to load, reach inside and get the 'follow @username'iframe
, set anonload
event on it, then wait for the second event to fire. - Using the
twttr.widgets.createTimeline()
function, which has an optional parameter for a callback. However, the callback is called when the content is ready (step 2), but not when the iframe is visible (step 4).
此时我可能忘记了更多组合.我知道存在一个使用 Twitter widget.js
的 github gist,但会为其添加回调.我无法让它工作.
There's probably a few more combinations I forgot at this point. I know there exists a github gist that uses the Twitter widget.js
, but adds callbacks to it. I was unable to get this to work.
对于日志问题很抱歉,但我希望有人能够提供帮助.谢谢.
Sorry for the log question, but I hope someone is able to help. Thanks.
推荐答案
当你复制和粘贴从 Twitter 获得的代码时,你必须替换这个:
When you copy and paste the code you get from Twitter, you have to replace this:
<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 函数是您的回调,它会在您的嵌入式时间轴加载和呈现时运行.
Of course, the doSomething function called above is your callback that runs when your embedded timeline loads and renders.
另外,我猜这个解决方案在 Internet Explorer 中不起作用,因为它不支持脚本元素的 onLoad 事件.不过有解决方案.
Also, I guess this solution doesn't work in Internet Explorer since it doesn't support onLoad events for script elements. Yet there are solutions for that.
最后,您可以在我编写的 Twitter 嵌入式时间线抓取工具中看到我对此问题的处理方法.
这篇关于Twitter 嵌入式时间线回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!