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.
Related
I want to set the iframe height depending on the content height, here below code is working for local links, but i want to do it on dynamically.
please help.
<iframe id="frameDemo" src="https://myvook.blogspot.com"></iframe>
<script>
$(document).ready(function() {
$( "#frameDemo" ).on('load', function() {
var mydiv = $(this).contents().find("body");
var h = mydiv.height();
$("#frameDemo").height(h);
});
});
Following up with what Rory said, it's not possible to set the iframe height before before the iframe has been loaded since you'll be pulling content from another domain.
However, it is possible to set the height of the iframe after you've downloaded the content. Here is how I've tackled it:
function noteContentIframeLoaded(iframeId) {
// See http://stackoverflow.com/a/5788723 for how to implement this function
var iframeElement = $("#" + iframeId)[0];
setTimeout(function() {
setIframeHeight(iframeElement);
}, 10);
}
function setIframeHeight(iframe) {
if (iframe) {
if (iframe.contentWindow || iframe.contentDocument) {
var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
if (iframeWin.document.body) {
iframe.height = (iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight);
}
}
}
}
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()
First post here.
So I am pretty good with my HTML and PHP, but fail at JS.
I am trying to make a simple toggle using images.
HTML:
<img src="clear.png" id="imgClickAndChange" onclick="changeImage()">
JS:
<script language="javascript">
function changeImage() {
if (document.getElementById("imgClickAndChange").src == "clear.jpg")
{
document.getElementById("imgClickAndChange").src = "full.jpg";
}
else
{
document.getElementById("imgClickAndChange").src = "clear.jpg";
}
}
This code does not work as the script is receiving the src as its full path and not just "clear.jpg".
Not a clue how to get around this.
I've tried using substr, that didn't work.
I wouldn't mind using the full path but the location could be relative on my server.
Rhys
var imgClickAndChange = document.getElementById("imgClickAndChange");
if (imgClickAndChange.src.indexOf("clear.jpg") !== -1){
imgClickAndChange.src="full.jpg"
}else{
imgClickAndChange.src="clear.jpg"
}
First off, you have clear.png in your html snippet, but are checking for clear.jpg in your javascript. After you get that cleared up...
You can use the getAttribute method to check for the "raw" contents of the attribute:
document.getElementById("imgClickAndChange").getAttribute('src'); // clear.png
Or you can use indexOf, as #manraj82 suggests, to check if "clear.jpg" exists in imgClickAndChange's src property:
document.getElementById("imgClickAndChange").src.indexOf("clear.jpg") // numeric index of "clear.jpg" or -1 if not found
Use a regular expression or split to get the section of the URL after the last / and compare that to the value you are testing against.
Alternatively, test with indexOf.
You can inject a flag to HtmlElement to store the state.
var img = document.getElementById('toggle_img');
img.onclick = function()
{
img.src = img.isOff ? 'on.png' : 'off.png';
img.isOff = !img.isOff;
}
See it in action on jsfiddle
I'd suggest the following:
function changeImage () {
var img = document.getElementById('imgClickAndChange'),
src = img.src;
img.src = src.indexOf('clear') > -1 ? 'full.png' : 'clear.png';
}
JS Fiddle demo.
Or:
function changeImage() {
var img = document.getElementById('imgClickAndChange'),
src = img.src;
img.src = src.replace(/(clear)|(full)/, function (a) {
return a == 'clear' ? 'full' : 'clear';
});
}
JS Fiddle demo.
To make it a little more easily-extensible (allowing you to pass in any img element, and using an arbitrary length of images/URLs to toggle between):
function changeImage(el) {
var self = el,
src = self.src,
toggleBetween = self.getAttribute('data-images').split(',');
for (var i = 0, len = toggleBetween.length; i < len; i++) {
if (src.indexOf(toggleBetween[i]) > -1) {
self.src = (i + 1 == len ? toggleBetween[0] : toggleBetween[i + 1]) + '.png';
}
}
}
Using the HTML:
<img src="clear.png" id="imgClickAndChange" data-images="clear,full,arbitrary,other,images" onclick="changeImage(this)" />
JS Fiddle demo.
And, finally, to remove the onclick event-handler, binding the event-handling in the script, rather than in the element itself to reduce the use of obtrusive (and difficult to maintain) JavaScript:
function changeImage(el) {
var self = this,
src = self.src,
toggleBetween = self.getAttribute('data-images').split(',');
for (var i = 0, len = toggleBetween.length; i < len; i++) {
if (src.indexOf(toggleBetween[i]) > -1) {
self.src = (i + 1 == len ? toggleBetween[0] : toggleBetween[i + 1]) + '.png';
}
}
}
var elem = document.getElementById('imgClickAndChange');
elem.addEventListener('click', changeImage);
<img src="clear.png" id="imgClickAndChange" data-images="clear,full,arbitrary,other,images" />
JS Fiddle demo.
References:
Element.getAttribute().
JavaScript Regular Expressions.
String.indexOf().
String.split().
String.replace().
Basically, im making a javascript to refresh a page and it will find the price and buy the item when it goes up for the price desired.
I got it to work without the iframe, but I need to to work in the iframe, which is the problem ive reached.
If you went to this page: [ http://m.roblox.com/items/100933289/privatesales ]
and ran this code:
alert(document.getElementsByClassName('currency-robux')[0].innerHTML);
You would get an alert for the lowest price. In the code, this doesnt work (Hence, my problem.)
Try running the code below on this page to get it to work [ http://www.roblox.com/Junk-Bot-item?id=100933289 ]
var filePath = document.URL;
var itemid = filePath.slice(((filePath.search("="))+1));
var mobileRoot = 'http://m.roblox.com/items/';
var mobileEnd = '/privatesales';
var mobileFilePath = mobileRoot+itemid+mobileEnd;
var iframe2 = '<iframe id="frame" width="100%" height="1" scrolling="yes"></iframe>';
document.write(iframe2);
var iframe = parent.document.getElementById("frame");
iframe.height = 300;
iframe.width = 500;
iframe.src = mobileFilePath;
var price;
var snipe = false;
var lp = Number(prompt("Snipe Price?"));
document.title = "Sniping";
function takeOutCommas(s){
var str = s;
while ((str.indexOf(",")) !== -1){
str = str.replace(",","");
}
return str;
}
function load() {
if (snipe == false) {
tgs = iframe.contentDocument.getElementsByClassName('currency-robux');
price = Number((takeOutCommas(tgs[0].innerHTML)));
alert(price);
}
}
iframe.onload = load;
You might try having both pages — the one from "m.roblox.com" and the one from "www.roblox.com" — add the following up at the top of the head:
<script>
document.domain = "roblox.com";
</script>
Code from the different domains won't be allowed to look at each others page contents, but if you set the domains to the same suffix then it should work.
If you can't get it to work by sharing the same document.domain="roblox.com" code then you can try posting messages to the iframe.
Put this inside the iframe page:
window.addEventListener('message',function(e) {
});
In the parent page execute this to pass a message (can be a string or object, anything really) to the iframe:
document.getElementById("frame").contentWindow.postMessage({ "json_example": true }, "*");
Put this in the parent to listen for the message:
window.addEventListener("message", messageReceived, false);
function messageReceived(e) {
}
From inside the iframe posting a message back out:
window.parent.postMessage('Hello Parent Page','*');
Hey guys, I have the following code. It is basically a gallery script and when I mouse over the thumbnail, it will change the a bigger version of the thumbnail:
$.fn.CloudZoom = function (options) {
try {
document.execCommand("BackgroundImageCache", false, true);
} catch (e) {}
this.each(function () {
var relOpts, opts;
eval('var a = {' + $(this).attr('rel') + '}');
relOpts = a;
if ($(this).is('.image')) {
$(this).css({
'position': 'relative',
'display': 'block'
});
$('img', $(this)).css({
'display': 'block'
});
if ($(this).parent().attr('id') != 'imageBox') {
$(this).wrap('<div id="imageBox"></div>');
}
opts = $.extend({}, $.fn.CloudZoom.defaults, options);
opts = $.extend({}, opts, relOpts);
$(this).data('zoom', new CloudZoom($(this), opts));
} else if ($(this).is('.thumbs')) {
opts = $.extend({}, relOpts, options);
$(this).data('relOpts', opts);
$(this).bind('mouseenter click', $(this), function (event) {
var data = event.data.data('relOpts');
$('#' + 'mainImage').data('zoom').destroy();
$('#' + 'mainImage').attr('href', event.data.attr('href'));
// Change the small image to point to the new small image.
$('#' + 'mainImage' + ' img').attr('src', data.thumby);
$('#' + 'mainImage').CloudZoom();
return false;
});
}
});
return this;
};
The html reads as follows:
<li>
<a href="gfx/boss_black.jpg" class="thumbs" rel="thumby:'gfx/boss_black.jpg'">
<img src="gfx/boss-black-small.jpg">
</a>
</li>
What I want to do is to write the rel="" tag without the "thumby".
I want the rel tag look like this:
rel="gfx/boss_black.jpg"
When I do this, the JS doesn't work anymore. How do I change the JS to simply get the "rel"?
var img = $('#' + 'mainImage' + ' img'),
rel = img.parent().attr('rel'),
thumby = rel.substr(8, rel.length - 9);
img.attr('src', thumby);
I would recommend storing the alternative src attribute in an attribute other than rel though. A HTML5 data attribute would be a good candidate.
Also, that is a bizarre selector :)
If I understand correctly - there is a library called thumby that requires a special format for your rel tag that you do not want in your source.
I can see two possible soultions.
Try to execute the javascript that changes the rel tag before the thumby library is included. Javascript loads and executes in the order specified in your HTML document. Hopefully thumby will pick up the changed value, but the source html contains the old value.
Modify the thumby library - specifically the part that reads from rel, and maybe make it identify where to operate based on the class thumbs instead.
Something like:
<li>
<a href="gfx/boss_black.jpg" class="thumbs">
<img src="gfx/boss-black-small.jpg" rel="gfx/boss_black.jpg">
</a>
</li>
...
$('.thumbs img').hover(
function () {
var r = $(this).attr('rel'), a = $(this).attr('src');
$(this).attr({'rel':a,'src':r});
},
function () {
var r = $(this).attr('rel'), a = $(this).attr('src');
$(this).attr({'rel':a,'src':r});
}
);