Info before reading: this code is written in vanilla js / jquery.
I have a page with a product list with infinite products and I want to scroll a bit down, click a product, go to that product detail page and when I click the browser back button it sends me to the list page at the same height where I was scrolling. So basically a pain to set up without a framework to keep track of state.
I've managed to get a POC for this appending an iframe with the product details content page and place it "on top" of the page. This, however, does not work in Firefox. Does anyone have any idea why?
I thought it was a z-index issue, however the iframe's body is empty. This is the iframe in Firefox:
<iframe id="productDetails" class="ProductDetailsFrame js-product-details-frame" src="http://localhost:3000/ProductDetailPage.html?productId=1888" scrolling="yes" frameborder="0">
#document
<html>
<head></head>
<body></body>
</html>
</iframe>
Here is the function I use to append the iframe:
(...)
function getBaseUrl() {
var re = new RegExp(/^.*\//);
return re.exec(window.location.href);
}
(...)
urlRoot = getBaseUrl()[0];
productLoadedUrl = urlRoot + 'ProductDetailPage.html?productId=' + productId;
(...)
function addIframe() {
$('<iframe>', {
src: productLoadedUrl,
id: 'productDetails',
class: 'ProductDetailsFrame js-product-details-frame',
frameborder: 0,
scrolling: 'yes'
}).appendTo($body);
}
Related
So I am using the new Facebook plugin (Page Plugin) and have a hard time to get it responsive on window resize.
I have set the option data-adapt-container-width="true", but that only triggers when there i a page load/reload.
Please se my JSFiddle: http://jsfiddle.net/29zgc790/ (try it in exporer and if that dont work try my plunker: http://plnkr.co/edit/IPnjpJUXxkO4WTLFTTW0?p=preview) where i have set the start width for the plugin to max (500px), but I want to trigger a reload of the plugin when the container (window) gets smaller then the plugin at that particular time.
I am thinking about somthing like:
$(window).resize(function () {
//Do the reload of plugin
});
Hope you guys have an idea of an solution that can guid me in the right way.
Embed the iframe generated:
<iframe id="facebook" frameborder="0" allowtransparency="true" allowfullscreen="true" scrolling="no" title="fb:page Facebook Social Plugin" src="http://www.facebook.com/v2.5/plugins/page.php?adapt_container_width=true&app_id=&channel=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FTlA_zCeMkxl.js%3Fversion%3D41%23cb%3Df1ce7bfb%26domain%3Drun.plnkr.co%26origin%3Dhttp%253A%252F%252Frun.plnkr.co%252Ff152208424%26relation%3Dparent.parent&hide_cover=true&href=https%3A%2F%2Fwww.facebook.com%2Fmicrosoft&locale=en_US&sdk=joey&show_facepile=false&show_posts=true&small_header=true&width=500"
style="border: none; visibility: visible;width: 500px; height: 500px;" class=""></iframe>
Get parent width and set it into iframe and iframe's src attribute
$(window).resize(function() {
//Do the reload of plugin
var new_width = $("#facebook").parent().width();
$("#facebook").css("width", new_width);
var url = $('#facebook').attr('src').split("&width=");
url = url[0] + '&width=' + new_width;
$('#facebook').attr('src', url);
});
After a few days of trying to achieve this, I came up with a working solution!
I actually registered only to share it :)
Copy the iframe code of the page plugin here:
Facebook Page Plugin (go to "Get code" and then click on "iFrame" on the top of the window that just opened.)
Paste the code to your html inside a div with class fb-column, then remove the width and src attributes (paste the value of the src attribute - the long link - somewhere else, you will need it later)
Add this code to your main .js file (credit for calculating the box size and calling the function goes to Mugo Web
function resizeFBPlugin() {
//calculate parent box width
var container_width = (Number($('.fb-column').width()) - Number($('.fb-column').css('padding-left').replace("px", ""))).toFixed(0);
// set the src and replace the actual width with the calculated width.
document.getElementById("fb-column").src = //paster link from iFrame here. Be sure to keep everything as it is, only replace the number after &width= with container_width
// it should look something like this: 'https://www.facebook.com....&width='+container_width+'&height=......';
// NOTE: take note of the use of apostrophes and + signs
//set the width of the iframe
document.getElementById("fb-column").width = container_width;
};
// call the function on resize and on window load
$(window).on('resize', function() {
setTimeout(function(){resizeFBPlugin()}, 500);
});
$(window).on('load', function() {
setTimeout(function(){resizeFBPlugin()}, 1500);
});
That's it! You now have a fully responsive Facebook page plugin (of course, within the min 180px and max 500px width.
BTW, The Twitter plugin works perfectly. I have no idea why Facebook decided not to fix this... I suppose they don't have the money for the right developers :)
So after reading the documentation for the facebook web sdk I found this little function that reloads the iframe.
FB.XFBML.parse();
https://developers.facebook.com/docs/reference/javascript/FB.XFBML.parse
That solved my problem, but #LucaGiardina hade a good solution as well but I think its always a god practice to use the built in functions if thay exist.
I have found out some solution but i think the best one is at least for me is that setting the parent tag of fb-comment-wrapper in a certain responsive then use facebook built in css data-width:
<div class="fb-comment-wrapper">
<div class="fb-comments" data-href="{{request.build_absolute_uri}}"
data-numposts="3" data-width="100%">
</div>
</div`>
Ok, here's my situation:
I've been working on a chatroom type website for a side-project/hobby. The current layout uses html frames. The bottom frame is the "footer", or "message input" frame. The top frame is where the public messages are displayed. I use ajax to update the top frame every second. It works fine. My issue is this:
I need to be able to keep the top frame scrolled all the way to the bottom -- UNLESS the user scrolls back up to view old messages, for example. I currently have a function that keeps it scrolled down to the bottom, but every time ajax updates the page, it forces it back down to the bottom, so I can't scroll back up for more than about a second, and it's really frustrating. I have searched for a solution, but i've not found any that actually work for me. The function that I use to scroll to the bottom is as follows:
function jumpToPageBottom() {
$('html, body').scrollTop( $(document).height());
}
It does it's job, but again, I need it to stop forcing the page to the bottom if a user scrolls back up to view older messages.
UPDATE --
I should clarify, I'm using actual frames, rather than an iframe. My "index" page code is:
<FRAMESET ROWS="*,90">
<FRAME SRC="header.php" name="display" MARGINWIDTH="0" MARGINHEIGHT="0" FRAMEBORDER="NO">
<FRAME SRC="footer.php" name="message" SCROLLING="no" BORDERCOLOR="00FF00" MARGINWIDTH="0" MARGINHEIGHT="0">
</FRAMESET>
And the code that refreshes my chat messages is:
<script id="source" language="javascript" type="text/javascript">
function jumpToPageBottom() {
$('html, body').scrollTop( $(document).height());
}
$(function() {
startRefresh();
});
function startRefresh() {
setTimeout(startRefresh,1000);
$.ajax({
url: 'api.php', //the script to call to get data
data: "", //you can insert url argumnets here to pass to api.php
//for example "id=5&parent=6"
dataType: 'json', //data format
success: function(data) //on recieve of reply
{
//--------------------------------------------------------------------
// 3) Update html content
//--------------------------------------------------------------------
$('#output').html(data); //Set output element html
jumpToPageBottom();
}
});
};
</script>
Is the refreshing like that just a bad approach? Is the way that the div is updated causing some of my issues? I'm new to all of this (obviously) -- so any advice would be much appreciated.
The basic logic you need is:
var wasAtBottom = isAtBottom();
$('#output').html(data);
if (wasAtBottom) {
jumpToPageBottom();
}
With isAtBottom being from this answer:
function isAtBottom() {
return $(window).scrollTop() + $(window).height() === $(document).height();
}
Here's a working demo for you: http://jsfiddle.net/9q17euuo/2/
I have a tricky question.
All pages are within same server / portal.
I have a page that embeds iframe from the other page using the following code:
$('#mydiv').append('<p id="loading">Loading ...</p>');
$('#mydiv').append('<iframe id="myframe" name="myframe" class="myframe" onload="myframe()" style="display:none;"></iframe>');
$('#myframe').attr('src', 'https://mywebsite.com/page2');
function myframe() {
var $myframesearch = $('#myframe').contents();
$myframesearch.find("a").attr('target','_parent');
}
$('#myframe').load(function(){
$('#loading').remove();
$('#myframe').fadeIn();
});
All of the links within iframe have no href (but href="javascript:void(0)") and uses scripts within iframe to process the action dynamically.
Some links does open in new window some does not.
I would like to force all links to either open in new Tab, Window, or append to new Div, but none of the methods work, like base / parent, onclick / new window, _top, _parent, etc.
However, my idea was to hide and wait till the content of iframe is loaded after a click and then to append loaded content in new hidden div and then fade it in. When doing so the loaded iframe content resets back to default and not with new content.
Does anyone knows how this can be solved?
Thank you all!
So I check and it appears that other JavaScript overwrites the "a" tag action with some "data" field in the tag only for the "a" tags that contain "Open:" in their link.
I found solution to the problem below by the link for this "a" tag from another page bypassing the JavaScript overwriting:
$(function(){
$('#mydiv').append('<p id="loading">Loading ...</p>');
$('#mydiv').append('<iframe id="myframe" name="myframe" class="myframe" src="https://mywebsite.com/page2" onload="myframe()" style="display:none;"></iframe>');
$('#myframe').load(function(){
$('#loading').hide();
$('#myframe').fadeIn();
});
$('<div id="popup" style="display:none; width:1px; height:1px; position:absolute; top:0; left:0;"></div>').appendTo('html');
});
function myframe() {
var $myframesearch = $('#myframe').contents();
$myframesearch.find("a").attr('target','_parent');
$myframesearch.find('a:contains("Open:")').on('click',function(){
$(this).attr('data','');
var $texta = $(this).text();
var $text = $texta.replace(/Open: /,"");
$('#popup').load('https://mywebsite.com/page2' + ' a:contains("'+$text+'")', function(){
$('#popup a').each(function(){
this.href = this.href.replace(/https:\/\/mywebsite\.com\/page2\/a/, "https://mywebsite.com/page2");
this.click();
});
});
});
}
Hope this helps :)
Ok, I have 2 iframes inside a parent page (for whatever reason).
I have a navigation menu on parent page, which changes the source of iframe #1...
iFrame #1's job, is to display ANOTHER navigation menu... Like a subnavigation menu...
Now, how can I upon clicking an li inside iFrame #1, change the source of iframe #2? They're both on the same parent page...
Aside from failing miserably, I also get a warning from Chrome's Dev tools -
Unsafe JavaScript attempt to access frame with URL file:///C:/website/index.html from frame with URL file:///C:/website/news/navigator.html. Domains, protocols and ports must match.
Here's some code to make things slightly clearer:
The HTML
<!-- HTML for the parent page itself -->
<iframe id="frameone" src=""></iframe>
<iframe id="frametwo" src=""></iframe>
<button onclick="onenav('test.html')">Change 1st frame</button>
<!-- The following is the HTML that is loaded inside "frameone" -->
<button onclick="twonav('test2.html')">Change 2nd frame</button>
// Javascript
var one = document.getElementById('frameone');
var two = document.getElementById('frametwo');
function onenav(x){
one.src = x;
}
function twonav(y){
two.src = y;
}
To me, this makes sense, since this is all being executed on the parent page... On loading, I query the dev tools and I can see that both, 'one' and 'two' have frame elements... The first button works, the second one, doesn't...
Works for me when using parent.twonav
DEMO
var links = [
'javascript:\'<button onclick="parent.twonav(1)">Change 2nd frame</button>\'',
'javascript:\'Hello\''
];
var one, two;
window.onload=function() {
one = document.getElementById('frameone');
two = document.getElementById('frametwo');
}
function onenav(idx) {
one.src=links[idx];
}
function twonav(idx) {
two.src=links[idx];
}
How did you try to change the iframe source?
parent.document.getElementById('2').src = "the new url";
Did you try something like this? I assumed from your message that the id of the 2nd iframe is 2.
How to get iframe src page title and then set main page title
If you want to do it using jQuery:
var title = $("#frame_id").contents().find("title").html();
$(document).find("title").html(title);
You can do it only when pages are on the same domain, otherwise it's useless.
Granting that iframes src and the parent document src are the same domain:
Parent document:
<html>
<head><title>Parent</title>
<body>
<iframe id="f" src="someurl.html"></iframe>
<script>
//if the parent should set the title, here it is
document.title = document.getElementById('f').contentWindow.document.title;
</script>
</body>
</html>
someurl.html:
<html>
<head><title>Child</title>
<body>
<script>
//if the child wants to set the parent title, here it is
parent.document.title = document.title;
//or top.document.title = document.title;
</script>
</body>
</html>
Unless the webpage is in the iframe is from the same domain as the containing page, it is impossible.
If they do have the same domain, then try the following:
document.title = document.getElementById("iframe").documentElement.title;
One way you can share title and location:
document.write('<iframe src="http://www.yourwebsite.com/home.html?title='+document.title+'&url='+window.location+'" frameborder="0" scrolling="no"></iframe>');
and then you can read the parameters on home.html page.
This can be done using event listeners on the page. It's not particularly elegant, but the browsers I have tried it with support it (so IE9+, Firefox, Chrome).
In your main site page add the following javascript:
function setPageTitle(event) {
var newPageTitle = event.data
// your code for setting the page title and anything else you're doing
}
addEventListener('message', setPageTitle, false);
In the iFrame, you'll then need to have the following script:
var targetOrigin = "http://your.domain.com"; // needed to let the browser think the message came from your actual domain
parent.postMessage("New page title", targetOrigin); // this will trigger the message listener in the parent window