How to embed HTML page in a resizeable way? - javascript

I want to embed a page developed by me using AngularJS into another third-party page (that may/may not be using AngularJS). To the third party it should be just as simple as adding a small piece of code - just like what they do to embed tweets from Twitter or add a comment box from Facebook.
I tried using <iframe>, but when my page is larger than iframe's size, scroll bars appear which I don't want. How to embed my page so that scroll bars don't appear and it appears that the embedded page is part of the original third-party website?
The embeddable page contains something similar to tweets/Fb comment box.
PS: Assume I have no control over the third-party sites.
PPS (to avoid the confusion): I control the content of the embeddable page i.e. I have control over what's there inside the iframe. But I don't have any control over the page where this iframe will be put. I need a piece of code (JS/html) which can be given to others so that after they add this piece of code, they will have my content in their page.

A very basic example, all credit goes to giveforward.com:
<script type="text/javascript" src="https://www.giveforward.com/widget.js">
</script>
<script type="text/javascript">
BuildWidget('c8c3');
</script>
the included javascript file simply defines a couple of functions and writes it's own iframe to the page.
function BuildWidget(fid)
{
makeFrame(fid);
}
function makeFrame(fid)
{
document.write('<iframe frameborder="0" scrolling="no" src="https://www.giveforward.com/widgets/w/'+fid+'/?m=1" style="min-width: 240px; width:100%; max-width:295px; height: 450px;margin:auto;display:block;"></iframe>');
}
function BuildAffiliateWidget(affid, packet) {
if(typeof packet == 'object')
{
refid = (typeof packet.refid == 'undefined') ? '' : '&refid=' + packet.refid;
category = (typeof packet.category == 'undefined') ? '' : '&category=' + packet.category;
title = (typeof packet.title == 'undefined') ? '' : '&title=' + encodeURIComponent(packet.title);
callback = (typeof packet.callback == 'undefined') ? '' : '&callback=' + packet.callback;
gfid = (typeof packet.gfid == 'undefined') ? '' : '&gfid=' + packet.gfid;
}else
{
refid = title = category = callback = gfid = '';
}
document.write('<iframe frameborder="0" scrolling="no" src="https://www.giveforward.com/widgets/a/?m=1&affid=' + affid + refid + category + title + callback + gfid + '" style="min-width: 240px; width: 100%; max-width:295px; height:450px;margin:auto;display:block;" class="affiliate_iframe"></iframe>');
}
The url that the iframe points to can be the same url that you are having your users embed to their own iframe now.

Thanks to #TheGunner for pointing me in the right direction. But he didn't specify the resizing part. So if the embedded page is bigger than the iframe then scroll bars would appear. To prevent this, you can call window.PostMessage from the embeddable page and the listener will take care of the resizing part.
I have created a script which assigns dynamic id to the iframe, and this id is used later to resize.(My script takes care only the height of the iframe. If the embeddable page is responsive, width shouldn't be a problem).
Here is the content of widget.js (this contains the window.PostMessage listener and the code to create iframe):
(function() {
var func = function(e){
if (e.data.indexOf('iid:') === 0) {
var hashPos = e.data.indexOf('#');
var iid = e.data.substring('iid:'.length, hashPos);
var height = e.data.substring(hashPos + 1) + 'px';
document.getElementById(iid).style.height = height;
}
};
var old = window.onmessage;
if (typeof window.onmessage != 'function') {
window.onmessage = func;
} else {
window.onmessage = function (e, f, g, h) {
if (old) {
old(e, f, g, h);
}
func(e);
};
}
}());
var BuildWidget = function(url, width) {
var getNewIid = function() {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
};
var iid = getNewIid();
if(!width) {
width = 900;
}
var maxWidth = width + 'px';
document.write('<iframe id="' + iid + '" src="' + url + '?iid=' + iid + '" frameborder="0" scrolling="no" style="min-width: 300px; width:100%; max-width:' + maxWidth + '; display:block;"></iframe>');
};
var AddXWidget = function(width) {
var url = 'http://localhost:8080/embed';
BuildWidget(url, width);
};
Now give out the following script to third-party sites to enable them to embed your widget:
<script type="text/javascript" src="http://path/to/widget.js">
</script>
<script>
AddXWidget(400);
</script>
Now, the embeddable page(the page inside iframe) should call window.PostMessage() as follows:
window.top.postMessage('iid:' + iid + '#' + elem.scrollHeight, '*');
Here iid is the URL parameter iid obtained and elem is the element looked up using document.getElementById()

Related

Iframe resize, not working

I am hosting the site locally on my xampp but, this code should have auto adjust with the site size and view it but here I am not able to resize it nor I am able to view it( I just get a blank white screen in the iframe space) what am I doing wrong, Please suggest me if there is an easier way to it .Here is the code:
< SCRIPT LANGUAGE = javascript >
function reSize() {
try {
var oBody = ifrm.document.body;
var oFrame = document.all("ifrm");
oFrame.style.height = oBody.scrollHeight + (oBody.offsetHeight - oBody.clientHeight);
oFrame.style.width = oBody.scrollWidth + (oBody.offsetWidth - oBody.clientWidth);
}
//An error is raised if the IFrame domain != its container's domain
catch (e) {
window.status = 'Error: ' + e.number + '; ' + e.description;
}
}
< /SCRIPT>
<BODY onload=reSize()>
<iframe onresize=reSize() id=ifrm src="http:/ / www.twitter.com "></iframe>
</BODY>

It is possible to Resize an iframe without reloading the frame?

Hi Stack Overflow Community.
I have a problem. I have a process with an iFrame.
This process have some Javascript to set iFrame height based on iFrame content. I think its not enough, so I decided to make an automatic resize of the iFrame height based on content changes without reloading any iFrame or process. Unfortunately, I tried but was unable to due to doubts. I searched everywhere in Stack Overflow but I didn't found the solution.
Rules:
Auto Height resize in the iFrame.
No reloads in the parent window or iFrame.
No triggers, no Interval.
Just everything automatic.
Window and iFrame are in the same domain.
Could you please help me?
Thanks, and sorry for bad english.
My Actual CODE:
if(document.getElementById("frame") != undefined)
{
var frame = document.getElementById("frame");
$(frame).load(function(){
var frame_height = frame.contentWindow.document.body.scrollHeight + 'px';
frame.setAttribute('style', 'height:' + frame_height + ' !important');
console.log('its this loading?');
contentBasedIframeResize(); //this is worthless, just testing. isn't dynamic right now. need fix.
// As soon as the frame finish the load, this frame height will be based in the frame content
});
function contentBasedIframeResize()
{
var add_button = $(frame).contents().find(".some_obj"); //preparing the trigger
var remove_button = $(frame).contents().find(".some_obj"); //preparing the trigger
if(add_button != undefined)
{
$(add_button).click(function(){
var add_height = frame.contentWindow.document.body.scrollHeight + 'px';
frame.setAttribute('style', 'height:' + add_height + ' !important');
});
}
if(remove_button != undefined)
{
$(remove_button).click(function(){
var remove_height = $("#frame").contents().find("#table_obj").height();
remove_height = parseInt(remove_height) + 100; //hardcoded
frame.setAttribute('style', 'height:' + remove_height + 'px !important');
console.log("its this working v2?");
});
}
}
}
Try this,
function resizeIframe(obj)
{
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
}
$('iframe').load(function(){
resizeIframe(this);
});

Bootstrap Modal Window not recognize all the variations of YouTube URLs

On the Internet I found a jQuery code that works very well to open YouTube video in modal form. I change some dteails and everything was fine until I realized that do not recognize all the variations of YouTube URLs.
All I need is to extract the YouTube ID and put it in the right place. I wrote a regex and combined several versions but does not work with every URL.
This is my code:
$('a[href^="https://www.youtu"]').on('click', function(e){
var YouTube=$(this).attr('href').replace(/feature=player_embedded[&\w]*(?!['"][^<>]*>|<\/a>)/ig, "").replace(";", ""); // replace player_embedded
preg=/(?:http|https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=))([\w\-]{10,12})\b[?=&\w]*(?!['"][^<>]*>|<\/a>)/ig,
youtubeID=YouTube.replace(preg, '$1');
if (youtubeID!="" && (YouTube.indexOf('v') > -1 || YouTube.indexOf('embed') > -1))
{
// Prevent opening of external page
e.preventDefault();
// Variables for iFrame code. Width and height from data attributes, else use default.
var width = $(window).width(),
vidWidth = 800, // default
vidHeight = 450; // default
if ( $(this).attr('data-width') ) { vidWidth = parseInt($(this).attr('data-width')); }
if ( $(this).attr('data-height') ) { vidHeight = parseInt($(this).attr('data-height')); }
// responsive debug
var vidWidth = (width>vidWidth?800:(width-60));
var iFrameCode = '<div class="video-container"><iframe width="' + vidWidth + '" height="'+ vidHeight +'" scrolling="no" allowtransparency="true" allowfullscreen="true" src="https://www.youtube.com/embed/'+ youtubeID +'?controls=0&autohide=1&autoplay=1&iv_load_policy=3&theme=light&rel=0&showinfo=0" frameborder="0"></iframe></div>';
// Replace Modal HTML with iFrame Embed
$('#mediaModal .modal-body').html(iFrameCode);
// Set new width of modal window, based on dynamic video content
$('#mediaModal').on('show.bs.modal', function () {
// Add video width to left and right padding, to get new width of modal window
var modalBody = $(this).find('.modal-body'),
modalDialog = $(this).find('.modal-dialog'),
newModalWidth = vidWidth + parseInt(modalBody.css("padding-left")) + parseInt(modalBody.css("padding-right"));
newModalWidth += parseInt(modalDialog.css("padding-left")) + parseInt(modalDialog.css("padding-right"));
newModalWidth += 'px';
// Set width of modal (Bootstrap 3.0)
$(this).find('.modal-dialog').css('width', newModalWidth);
});
// Open Modal
$('#mediaModal').modal();
}
});
Thanks!

Can't change iframes onload listener in IE9

I have the following code within an external javascript file.
jQuery(function ($) {
//////////////////////UPCOMING EVENTS JSON SERVER START///////////////////////////
var eventList = $("#eventList"); //cache the element
$.getJSON("/JsonControl/Events.json", function (jsonObj) {
val = "";
for (var i = 0; i < jsonObj.events.length; ++i) {
val += "<p>" + jsonObj.events[i].dateMonth + "/" + jsonObj.events[i].dateNumber +
"/" + jsonObj.events[i].dateYear + " - <span id='EL" + i + "' class='link' " +
"onclick=plotEvent(" + i +")>" + jsonObj.events[i].title + "</span></p>";
}
eventList.html(val);
});
//////////////////////UPCOMING EVENTS JSON SERVER END/////////////////////////////
});
function plotEvent(index)
{
$.ajax({
url: "/JsonControl/Events.json",
dataType: 'json',
async: false,
success: function (jsonObj)
{
var eventBox = window.frameElement;
alert("This alert fires in all browsers, including IE9")
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
eventBox.src="/Event htms/Event.htm";
}
});
}
The page that loads this script is in the iframe itself. A very similar function called in a different external js file, from the main page outside of the iframe (for a different but similar purpose) works in all browsers just fine. The only difference is that with this code I have to target the onload of the iframe from within the iframe, instead of just grabbing the iframe by id. I then attempt to change, the onload of said iframe, for use with the next internal iframe page (which is why I need to preserve the json array index [i] when dynamically writing the first iframe page's innerHTML.
Sorry if that was a bit wordy, and/or confusing, but suffice it to say that with using the above-pasted code, I have no problems... except with IE (tried in IE9). I have tried dozens of examples and supposed solutions, but nothing has worked. Using IE9.
Here's what I mean when I say 'it doesn't work in IE9':
This part of the code within plotEvent() doesn't fire:
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
Is there any solution to this problem, or is this sort of thing why iframes aren't used more often (that is, that IE doesn't fully support them)?
Try eventBox.contentWindow.onload or maybe $(eventBox).load(function)

JS for loop to set HTML Object arguments

I am trying to write a JS class to easily create Iframe HTML objects.
This is my code:
var Iframe = function (params) {
var src = params.src || '';
var appendTo = document.getElementById(params.appendId) || document.body;
var iframe = document.createElement('iframe');
iframe.src = src;
if (typeof params.attrs != 'undefined') {
for (attr in params.attrs) {
iframe.attr = params.attrs[attr];
alert('attr: ' + attr + "\nIframe.attr: " + iframe.attr);
alert(params.attrs[attr]);
}
}
appendTo.appendChild(iframe);
}
When the DOM loads:
var myIframe = new Iframe({
src: 'http://www.example.com',
appendId: 'iframeDiv',
attrs: {height: '500px', id: 'ID'}
});
It alerts the expected values:
attr: height
Iframe.attr: 500px
and:
500px
But fails to set the arguments on the HTML, this is the generated source:
<div id="iframeDiv">
<iframe src="http://www.example.com"></iframe>
</div>
What's wrong?
How can I achieve this?
Thanks!
iframe.attr = params.attrs[attr];
I think you meant:
iframe[attr] = params.attrs[attr];
or:
iframe.setAttribute(attr, params.attrs[attr]);
You also forgot to declare attr, by the way.

Categories