Skip to content

Pym.js Tips & Tricks

Kavya Sukumar edited this page Jul 30, 2015 · 6 revisions

For creating embed.txt, we highly recommend using Pym.js, a Javascript library for responsively embedding iframes.

Here are a few easy ways to use Pym.js to add functionality to your embedded projects.

NOTE: In Pym.js parlance, the parent page is the page you embed the iframe in. And the child frame is the page that is embedded. For more info read Pym.js documentation.

Simple responsive embed

The following is a simple embed.txt.erb for your blueprint that makes the embed responsive.

<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%=data.autotune.slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script type="text/javascript">
	new pym.Parent('<%=data.autotune.slug %>__graphic', '<%=asset_url('/') %>');
</script>

Make sure that the file is saved as embed.txt.erb

In the blueprint's javascript add this

var pymChild = pym.Child();

Anytime you add or remove content to the blueprint's DOM, send the new height to the parent page like this

pymChild.sendHeight();

For Pym.Js to function correctly, make sure that the following css is applied to the child page.

html, body { width:auto; height:auto; }

Get parent page's URL for sharing

When a user clicks a share button from your blueprint, you often want to share the parent page's url and not the link to the child directly. Security concerns restrict communication between the parent and its embedded iframes. But Pym.Js's sendMessage function can be used to send the parent page's url to the blueprint.

Save the snippet below as embed.txt.erb

<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%= slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script>
	var pymParent = new pym.Parent('<%= slug %>__graphic', '<%= absolute_page_url %>');
	pymParent.onMessage('childLoaded', function() {
		pymParent.sendMessage('setShareUrl', document.URL);
	});
</script>

The script above waits for the child page to send a childLoaded message. Then it attempts to send its URL to the child. The child blueprint first has to notify the parent that it has finished loading. For this in the blueprint's javascript add the following

Create a Pym Child and send childLoaded message

var parentPageUrl = document.URL,
   pymChild = new pym.Child();
pymChild.sendMessage('childLoaded', 'ready');

Don't forget to continue to call sendHeight() when content height changes

Add a listener for the setShareUrl message as follows

  pymChild.onMessage('setShareUrl', function(Url) {
    parentPageUrl = Url;
  });

Scrolling the parent from the child

When the height of the content in the child iframe changes drastically, sometimes you are left with a scroll position on the parent that is not ideal. You can use Pym.js to scroll the parent page.

In this example, we will scroll the parent page to the start of the iframe

For this let's use the example above, but instead of sending just the parent page's url, let's also send the id of the div that contains the iframe.

The new embed.txt.erb looks like this

<div data-analytics-class="embed" data-analytics-viewport="autotune" id="<%= slug %>__graphic"></div>
<%=javascript_include_tag('pym') %>
<script>
	var data = {};
	data['url'] = document.URL;
	data['slug'] = '<%= slug %>__graphic';
	var pymParent = new pym.Parent('<%= slug %>__graphic', '<%= absolute_page_url %>', {xdomain: '.*\.voxmedia\.com'});
	pymParent.onMessage('childLoaded', function() {
		pymParent.sendMessage('shareInfo', JSON.stringify(data));
	});
</script>

The shareInfo handler stores the slug in addition to the parent page URL like this

pymChild.onMessage('shareInfo', function(data) {
    data = JSON.parse(data);
    parentPageSlug = data.slug;
    parentPageUrl = data.url;
});

Now for the actual scrolling, just call

pymChild.scrollParentTo(parentPageSlug);