1

I'm trying to asynchronously (or lazy load) this Reddit widget, but I'm having an issue.

Here's the basic code that works perfectly when directly in the html:

    <script src="http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off" type="text/javascript"></script>

If I try to move that over into my scripts.js where I execute other jQuery stuff, it ends up rewriting the entire DOM with the widget. I'm aware that loading that src in the browser shows the code that's being executed begins with document.write. So I'm guessing since it's loosing a reference point, it's overwriting the entire window.

Here are the two methods I had attempted and failed:

$('.redditdiv').html('<script src="http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off" type="text/javascript"></script>');

The other failed attempt:

var redditscript = document.createElement('SCRIPT');
redditscript.type = 'text/javascript';
redditscript.async = true;
redditscript.src = 'http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off';
$('.redditdiv').append(redditscript);

If anyone has a suggestion, that would be quite awesome. Thanks!

P.S. Bonus Question: Does anyone have a suggestion for this Twitter Widget too?

<script src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({version: 2,type: 'profile',rpp: 4,interval: 6000,width: 'auto',height: 300, theme: {shell: {background: '#ffffff',color: '#000000'},tweets: {background: '#ffffff',color: '#606060',links: '#4476cc'} }, features: {scrollbar: false,loop: false,live: false,hashtags: false,timestamp: true,avatars: false,behavior: 'all'} }).render().setUser('skattertech').start();
</script>
2
  • 1
    See Dynamically inserting javascript into HTML that uses document.write. Commented Nov 6, 2010 at 20:23
  • Matthew, thanks for the suggestion. I tried the simple version that Noah had suggested. It didn't seem to do anything. Could you possibly write out an example for one of the pieces of code above? (Sorry, I'm new this stuff.) Commented Nov 6, 2010 at 22:01

3 Answers 3

3

Adapting the script from the question mentioned by Matthew Flaschen, we can use something like this:

var content = '';
document.write = function(s) {
    content += s;
};

$.getScript('http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off', function(){
    $('body').append(content);
});

We're using the $.getScript function, which is especially designed to dynamically load scripts. The second parameter is the loaded callback, so the function passed to the function will get executed on load.

You should replace the 'body' selector with whatever element you need. Alternatively, if you don't need jQuery,

var s = document.createElement('script'),
    content = '';

s.src = 'http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off';

document.write = function(s) {
    content += s;
};

s.onload = function(){
    document.getElementById('reddit').innerHTML = content;
};

document.getElementsByTagName('head')[0].appendChild(s);

See: http://jsfiddle.net/8yg9x/ for the jQuery version, and http://jsfiddle.net/d95xh/ for the plain Javascript version

Sign up to request clarification or add additional context in comments.

6 Comments

Hey Yi, I've been using your first example for the past few weeks and it works great. I now have another small issue. I was trying to repeat that for a second widget on the same page. I re-used the code, but switched out all the variables and I'm appending to a different part of the page. The issue is that the initial document.write capture is appended into the final one. Any solution for using this idea more than once? Example: jsfiddle.net/82EbS/3
@Sahas Hmmm... there isn't a easy way to avoid this, because it's impossible to tell which script is calling the document.write function. You can place the second part in the callback for the first, but that will slow down the loading of the widgets, because now they can't both be loaded at the same time. However this seems to be the only obvious solution. See: jsfiddle.net/yijiang/82EbS/4
Yi, thanks for clarifying that. I found a simple solution. I just opened up http://www.reddit.com/static/button/button2.js It just creates a very basic iFrame. I can construct and inject it quite easily. This way, I can continue to use the document.write for the other reddit widget that leaves me with no other option. :) Thanks again!
One more question. Hope I'm not bugging you too much. :) I noticed that document.write holds up my entire javascript if reddit's servers happens to be responding slowly. Is there any trick to fix that issue?
@Sahas The solution you have there won't work, because of cross-domain restrictions. document.write should be synchronous, but since you've overridden it I don't see why that should be a problem. Of course, even if you didn't, I'm not sure how you would get around that problem - the code is native, and you really can't get around the problem. You can still try asking a new question though.
|
0

You can use

<script src='//redditjs.com/subreddit.js'></script>

or if you wanted to use more options. Details of the options can be found here.

<script src='//redditjs.com/subreddit.js' data-subreddit='aww' data-height='400' data-width='330' data-sort='hot' data-theme='dark' data-subreddit-mode='small' ></script>

The end result will looks like this.

https://i.sstatic.net/hzXhj.png

Comments

0

This method will Lazy Load Widgets only when it is visible to User, If the Widget is not scrolled into viewport it will not be loaded, it works like Lazy Loading an Image.

Add LazyHTML to Head.

<script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyhtml.min.js" crossorigin="anonymous" debug></script>

Wrap widgets in LazyHTML Wrapper.

Lazy Load Reddit Widget

<div class="lazyhtml" data-lazyhtml onvisible>
  <script type="text/lazyhtml">
  <!--
   <script src="http://www.reddit.com/domain/skattertech.com/new/.embed?limit=4&amp;t=all&amp;sort=new&amp;style=off" type="text/javascript"></script>
  -->
  </script>
</div>

Lazy Load Twitter Widget.

<div class="lazyhtml" data-lazyhtml onvisible>
  <script type="text/lazyhtml">
  <!--
<script src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({version: 2,type: 'profile',rpp: 4,interval: 6000,width: 'auto',height: 300, theme: {shell: {background: '#ffffff',color: '#000000'},tweets: {background: '#ffffff',color: '#606060',links: '#4476cc'} }, features: {scrollbar: false,loop: false,live: false,hashtags: false,timestamp: true,avatars: false,behavior: 'all'} }).render().setUser('skattertech').start();
</script>
  -->
  </script>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.