2013-07-22 31 views
9

Ich habe viel über Twitter's Embedded Timelines geforscht. Ich habe versucht herauszufinden, ob es möglich ist zu wissen, wann die Timeline fertig geladen ist und auf der Seite anzeigt. Diese issue has been requested ist aber noch nicht implementiert worden. Ich bin in eine Sackgasse geraten und hoffe, dass jemand mir helfen kann, die Lösung zu finden. Hier ist, was ich bisher gefunden:Twitter Embedded Timeline Callback

Der Code ein Embedded Timeline hinzuzufügen:

<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> 

Was passiert, wenn das Skript ausgeführt wird:

  1. Das Skript ersetzt den <a>-Tag mit ein Element.

  2. Der Inhalt der iframe sind bereit, aber das Avatar-Bild und die "Follow @Benutzername" -Schaltfläche werden nicht heruntergeladen. Das iframeheight Attribut wird auf 0 festgelegt, damit Sie den Inhalt ohne die Bilder nicht anzeigen.

  3. Das Avatar-Bild wird heruntergeladen, aber der Button "follow @username" wird noch heruntergeladen. Der Inhalt ist immer noch nicht sichtbar.

  4. Der Knopf 'follow @username' ist fertig mit dem Herunterladen. Das iframeheight Attribut wird festgelegt, um die Höhe des Inhalts des iframe übereinzustimmen. Die Zeitleiste ist jetzt sichtbar.

Nun, ich habe versucht, alles, was ich mir vorstellen kann, um herauszufinden, wenn die Timeline zu sehen ist (ohne mit setTimeout/Intervall). Das Ziel ist ein nicht abfragendes Ereignis/Funktion/Rückruf. Hier ist, was ich bisher ohne Erfolg versucht:

  • Einstellung Ereignis-Listener auf den iframe (wie onload, DOMContentLoaded, DOMFrameContentLoaded, usw.) zu wissen, wann der Inhalt fertig geladen ist. Dies funktioniert nicht, da das iframe kein src Attribut hat. Nachdem ich den Uglified-Code durchsucht habe (ich konnte keine unkomprimierte Version finden), schätze ich, dass er den Inhalt durch Schreiben in den Body der iframe einfügt.
  • Einstellen von Ereignis-Listener, wenn das height-Attribut sich auf iframe ändert. Theoretisch sollte dieses Ereignis dreimal ausgelöst werden: erstens, wenn der Inhalt geladen wird, zweitens, wenn height auf 0 gesetzt wird, und drittens, wenn height auf die vollständig geladene Zeitleiste eingestellt ist. Ich konnte das Ereignis jedoch nur für die ersten beiden Fälle und nie für das dritte (das, was ich eigentlich wollte) schießen lassen. Ich verwendete DOMSubtreeModified, onreadystatechange und onpropertychange, aber nur DOMSubtreeModified arbeitete für das Auslösen des Ereignisses.
  • Ereignis-Listener auf den Cotents der iframe setzen. Da JavaScript innerhalb der iframe von Twitter erreichen kann, ist es möglich, jedes Element innerhalb der iframe (wie document oder window) zu greifen. Durch das Hinzufügen von onload, DOMContentLoaded oder DOMFrameContentLoaded Ereignis-Listener auf der window oder document der iframe werden diese Ereignisse jedoch noch nicht ausgelöst.
  • Einstellen von Ereignis-Listenern auf der Schaltfläche "follow @username". Die Schaltfläche ist eigentlich eine iframe, die ein src Attribut hat. Durch das Setzen eines onload Ereignisses wird es ausgelöst, wenn es geladen wird. Das Ereignis onload wird jedoch immer zweimal ausgelöst. Das erste Mal, wenn das Herunterladen abgeschlossen ist, und das zweite, wenn die Verarbeitung abgeschlossen ist. Unmittelbar nach dem zweiten Trigger wird die Timeline angezeigt. Um dies zu implementieren, ist das ziemlich Hack (obwohl ich denke, alles ist), da Sie auf den Inhalt der iframe warten müssen, zu erreichen, erreichen Sie innerhalb und erhalten Sie die 'folgen @Benutzername' iframe, setzen Sie eine onload Veranstaltung darauf, dann warten auf die zweites Ereignis zu feuern.
  • Verwenden der twttr.widgets.createTimeline()-Funktion, die einen optionalen Parameter für einen Rückruf hat. Der Rückruf wird jedoch aufgerufen, wenn der Inhalt bereit ist (Schritt 2), aber nicht, wenn der Iframe sichtbar ist (Schritt 4).

Es gibt wahrscheinlich ein paar mehr Kombinationen, die ich an dieser Stelle vergessen habe. Ich weiß, dass es eine github gist gibt, die das Twitter widget.js verwendet, aber Rückrufe hinzufügt. Ich konnte das nicht zur Arbeit bringen.

Sorry für die Log-Frage, aber ich hoffe, dass jemand helfen kann. Vielen Dank.

Antwort

9

Beim kopieren und fügen Sie den Code, den Sie von Twitter erhalten, müssen Sie diese ersetzen:

<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> 

mit diesem:

<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> 

Natürlich ist die oben genannte DoSomething-Funktion Ihr Callback, der ausgeführt wird, wenn Ihre eingebettete Zeitleiste geladen und gerendert wird.

Auch, ich denke, diese Lösung funktioniert nicht in Internet Explorer, da es keine OnLoad-Ereignisse für Skriptelemente unterstützt. Yet there are solutions for that.

Zuletzt können Sie meine Annäherung an dieses Problem in the Twitter embedded timeline scraper I wrote sehen.

+0

Wie funktioniert dieser Schaber? Ich habe es mir angesehen, und Sie greifen über ein Skript von einer anderen Domäne auf den Inhalt eines IFrame zu, was Sicherheitsfehler verursacht. Es ist eine coole Idee, ich habe mich nur gefragt, ob du etwas extra getan hast, um das zu umgehen. – Andy

+0

@Andy versucht der Scraper nicht auf einen IFrame von einer anderen Domäne zuzugreifen. Das Twitter-Widget enthält ein Skript, das ein IFrame dynamisch erstellt, es jedoch nicht direkt aus einer anderen Domäne lädt, sodass beim Versuch, es zu scrappen, keine Sicherheitsfehler auftreten. – joom

+0

Ich wusste nicht über die 'twttr.events.bind'. Es scheint auch zur richtigen Zeit zu schießen. Für alle anderen, die sich darüber wundern, welche Ereignisse bindbar sind, finden Sie hier Informationen zu allen Veranstaltungen: https://dev.twitter.com/docs/tfw/events. Auch IE8 und darunter unterstützt keine Onload-Ereignisse für Skripts. IE9 + tut (siehe http://peissgood.org/test/script-link-events/). –

8

Ich bin gonna Post meine Lösung hier, auch wenn es 1 Monat bei someones gerade gewesen findet diesen Beitrag wieder, was ich tun musste, war abzufragen, bis die iframe für Rückruf einer Breite> 1 als Indikator hatte

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); 
} 
+0

Je nachdem, was Sie versuchen, wenn dies der Fall ist, zu tun, möglicherweise nicht die Breite Überprüfung versuchen, den Wert der Höhe Prüfung statt. Ich musste das tun, damit mein Ding funktioniert. – rclai

1

Sie könnten versuchen, die Javascript-Factory anstelle der Attributbindung zu verwenden. Die createTimeline-Methode gibt ein Versprechen zurück, sodass Sie Ihre Post-Load-Aktivitäten dort verketten können. Siehe twitter Dokumentation: 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(); 
}); 
Verwandte Themen