Dynamically change iframe's content - javascript

I have an iframe tag and I want to dynamically change it using jquery animation. So for example the iframe sits on the home page, and if i click the about link, it will load the about.html and when its ready it will slide it down using animation.
I have the basic logic for it but then came about this
problem:
When I refresh the page it loads back the content of the index.html page, and what I want is that when I refresh it, it still keeps the contents of about.html.
About
<iframe id="content" name="content" align="top" src="index.html"
frameborder="0" width="100%" height="1200px" scrolling="no">
</iframe>
this is just the most basic logic, but I need help on how do I achieve the refreshing part/
and what if i dont include them in the same page but I still want to animate the page transitions. so when the users clicks a link to a new page, it will load it, and then animate it.How can I achieve this. Because recently I saw a jquery plugin callen LocalScroll and they achieve this effect, but i couldnt get it to work for new pages

Your reference to the jQuery plugin LocalScroll is on the right track. In fact, if you could implement it properly I think it would solve your problem.
Anchor-based navigation, as used in this plugin, jQuery Mobile, and other places, will update the window.location object and also be reflected in the browser's address bar so that, when an explicit page refresh occurs, the hashed location is preserved.
The answer, then, is to have a script which can parse this local link from the address. Here's a generic JavaScript code block to demonstrate this:
window.onload=function() {
var URLParts=window.location.toString().split('#');
if(URLParts.length>1)
var lastPage=decodeURI(URLParts[1]);
else
return false;
if(lastPage)
iframe_load(lastPage,'content');
}
function clear_last_page(location) {
var URLParts=location.split('#');
if(URLParts.length<=1)
return location;
URLParts.pop();
return URLParts.join('#');
}
function iframe_load(url,targetID) {
document.getElementById(targetID).src=url;
var location=clear_last_page(window.location.toString())+'#'+url;
window.location.href=location;
}
How it Works
When the window onLoad event is triggered, the URL is searched for anchor (hashed) links. If found, we will assume that this is a reference to a page and so then pass it to iframe_load().
This function does two things. First, it points your target inline frame to the page passed via url parameter. Second, it points the parent frame to a fictitious anchor, which will be preserved even after the page is refreshed.
Therefore, when you refresh the parent frame, that anchor text is grabbed, parsed, and used to re-load the last loaded inline page.
The function clear_last_page() is simply a helper function that prevents additional anchor links from being appended to the URL.
Demonstration
Visit this URL:
http://gocontactform.com/stackoverflow/dynamically-change-iframes-content/
Click the link "Page 2" to see the change. Then refresh the page.
Noteworthy
Be advised that this solution technically takes over the normal function of anchoring. So if you attempt to use anchor links normally on the page, you may get undesirable results.
You are forced to rely on iframe_load() for any links bound for that inline frame, instead of what you modeled in your question (traditional linking with a target attribute).
I might also suggest that you define no default src attribute inline. Rather, you could add to the onLoad handler a call to iframe_load('page1.html','content') and that will prevent the unnecessary attempt to load the default page when you are refreshing with anchored links in the address.
There are also other ways to accomplish what you are asking. But I believe that this solution is easy to understand and implement.
Hope that helps!

You can use the following to change the src attribute of the iFrame:
$("#content").attr('src', 'http://mysite.com/newpage.html');
Oops, looks like I misread the question.
If you want to slide it down, you can bind an event handler to the load event (jQuery doc) to do something when the frame loads.
$("#content").hide();
$("#loadLink").click(function() {
$("#content").hide();
$("#content").attr('src', 'http://mysite.com/newpage.html');
});
$("#content").load(function() {
$(this).slideDown();
});
In this example, the iframe is hidden when you click the link, and when it is ready, it slides down.
Demo
Edit: still misread it!
To save the state of which page is last shown in the iframe, you can use HTML5 localStorage.
In the load event of the iframe save the page that it's currently showing.
localStorage['lastPage'] = "about.html"
and then load it back using localStorage['lastPage'] on page load.
Updated demo showing both sliding and keeping the page after refresh.

Not possible. When you refresh a page, your browser is supposed to get the page from the server, dropping all JS data.
History API can help, but only for the newest browers.

Whenever the page loads you need to check something to know what the last src iframe loaded. By default, no browser can know this. One way to do this is to change the hash of your page when hit the click, and whenever page loads, you check if exists this hash and trigger some link with the hash.
I write this: http://jsfiddle.net/estevao_lucas/revsg/4/
Like said Michael, History API can help you.

Related

Changing the location hash of a parent window & running a script afterward

I'm developing a small personal website, and for a main part of the navigation, I'd like to use location hashes. I have a link on a page embedded in an iframe that I would like to be able to change the location hash of the parent page, but I can't seem to get it to work the way I want.
To be more specific, I can get it to work if I ONLY want to change the location hash, but I also want to run a script on the parent window to check the hash after it has been changed. Here is what I did for only changing the hash:
Click Me!
And this is what I've tried, to make it run a function afterward:
<a onclick='parent.location.hash="foobar";parent.theFunction();' href="#" >Click Me!</a>
When trying this, it doesn't even seem to change the hash in the first place, which makes me think there's some other way of having it change the parent hash via JS that I'm missing.
Whoops, I ended up finding out that the hashchange event exists.
For anyone else looking to do a similar thing, here's how you'd do it:
window.addEventListener("hashchange", yourFunction)
function yourFunction() {
// do stuff
}
in your parent page - the listener will run the function yourFunction whenever the page hash changes.

Google Tag Manager not firing on link click in site footer?

This is my first post - I have searched for the answer in other questions but couldn't find anything so hoping that someone can help with this specific question?
I'm trying to track a link that's sat in a 'floating' bar in the footer of this site:
The link is #browsealoud - which is when you click on Screen reader - which upon clicking opens a pop-up which then reads out text (to assist those with sight problems).
I have set up the Tag and Trigger in Google Tag Manager, and know it works fine as when I insert the below link code in the body content, the Event is tracked in Google Analytics.
However, as this link sits in the floating grey bar in the footer, the trigger doesn't fire and I can't quite work out why. What is the best solution to allow me to track link clicks on this particular link (which appears on all pages)?
<h6>Screen reader</h6>
UPDATE: Screenshot of tag, trigger and variables below, as requested.
screenshot
It looks to me as though you've already fixed this, as I think I can see a GA event firing whenever I click.
In any case, I think your problem is likely that there are two different places that you can click to obtain the same result; the text 'Screen reader' is actually a child of the element that includes the arrow, so clicking it will obtain a different set of attributes.
I woudl set up a custom javascript variable Parent href that reads the href of the parent of the clicked object. For example...:
function() {
return {{Click Element}}.parentElement.href;
}
And then set up a trigger that fires when either Click URL or Parent href is equal to #browsealoud.
Thanks for the screenshots. I believe what you need to do is to simply enable the History listener variables
The reason is because you are trying to track a URL fragment (ie. it has a hash) which GA doesn't track by default but can be tracked through GTM via the history listeners. I would also change your trigger to this:

Reliably jumping to named anchor on dynamically generated page?

I have a web page which is dynamically built by the client. It generates dozens of list items each with its own named anchor. The side of the page has a fixed table of contents (TOC) with hyperlinks that point to the named anchors. This allows the user to click a TOC entry a jump to the item.
The trouble I am encountering is that on the initial page load the page is dynamically generated and so it cannot scroll to the item in the initial hash of the URL using the default behavior of a browser. Additionally, when the user switches to a different book the page is completely regenerated with new content and a new starting hash. Same problem: since the hash preexists the content, it doesn't situate itself with the item already in view.
I nearly solved this with JavaScript by awaiting the rendering and then jumping to the hash using scrollIntoView method on the appropriate element.
The next problem is that the stylesheet is not fully applied by the time scrollIntoView is called and so the final position of the item is unknown. I see the unstyled item scroll into view, but once styling is applied the positioning is lost. I put a 1 second setTimeout in place to delay the scrollIntoView call. This works but feels fragile.
Are there reliable techniques for jumping to a named anchor when the content comes after the hash is in place? If I knew when the CSS was done styling content that might help. Alternately, it might be useful to trigger an event once the height of the page stabilizes (thus signaling the finalization of CSS styling).
I had a similar problem, although in my case only the table of contents and named anchors were autogenerated in the onload handler - not the rest of the page content. I solved the initial hash problem by adding the following code to my onload handler after generating the anchors:
if (location.hash)
{
var requested_hash = location.hash.slice(1);
location.hash = '';
location.hash = requested_hash;
}
I had to set the hash to '' before setting it back to the requested name to make the browser respond. This seemed to work in all the browsers I tried (Opera, Chrome, Edge, IE, FF).
You can use jQuery if you will always know the name of the element you want to set focus to. You can run this after your page has loaded:
$( "#targetElementGoesHere" ).focus();
Edit: To scroll to that, check out https://github.com/flesler/jquery.scrollTo
I think the answer you require was answered by this guy...
How to wait until a web page is loaded with javascript?
So, something like this...
document.onload = function(){
scrollIntoView...
}

Handle browser back button with Javascript / different approach possible by using anchors?

I'm currently struggling with a good navigation on a website using Ajax calls and unobstrusive JS. I'm catching the click event on links, load the content, attach it to a div and then return false. This works quite well and also allows Google to crawl the site with speaky URLs.
But I didn't know how to deal with the browser back button. I found this solution to catch the event when the user clicks on the back button:
http://www.bajb.net/2010/02/browser-back-button-detection/
It works quite well. But I also want the back button to work normally when the user found the website via a link and wants to return to the previous page (I don't want to trap anyone).
When I thought about it the best way would be to use anchors. The normal back button supports them and you can go back in history without reloading the page (/#1 <- /#2 <- /#3 etc.)
It would work like this:
Use normal URLs in the link, but catch the click event
When user clicks, load content and attach it to a DIV
Change the window.location, using an anchor (e.g. 'domain.com/#products/women-clothing' with window.location="#products/women-clothing";)
When the window.location changes, get the anchor, read out the path and get the content via ajax, attach it to a DIV
Only the last part isn't really clear for me and I could need help here.
Finaly, my question: Does this make any sense?
Thanks!
Just add the href to window.location.hash after loading the content into a div. Then you can use that back button detection script to load what ever is in the hash.
I solved the problem by using this great jQuery Plugin: History.js
Thanks!

history.back(); doesn't trigger $(document).ready();

I have a webpage that use $(document).ready() to build the interface. Then the user can go to a child page, and to go back to the original page he can press the browser's "previous" button or a "Return" button in the page which triggers a history.back();. Back on the original page, $(document).ready() is not triggered so the page is missing information.
Is there a way to trigger it automatically like if it was a "real load"?
edit
placing an alert in it, the alert is popped but stuff is missing in my interface like if some part of the ready event is missing. Investigating...
edit 2
hahahahaha in document.ready I click some checkbox which are supposed to be unchecked. When I "back" on this page, they are checked so they become unchecked because I reclick them.
Sorry, this is completely my bad :(
A quick solution to this problem, use "onpageshow" instead.
window.onpageshow = function(event) {
//do something
};
If the user uses the Back button to navigate and you require a full reload of the page, you can set the NO-CACHE policy of the page.
This way the browser is forced to reload the page from the server, even using the Back button.
1.) put scripts at the bottom of your page.
2.) execute plugins and whatnot in your last script tag(s).
3.) Do not use onDomReady implementations at all, it's redundant.
People are so accustomed to onload or ondomready, they overlook the fact that putting your scripts at the bottom of a page does virtually the same thing without the need to poll and see if your html is available.
Furthermore, it's also good practise as your scripts do not block html/css rendering either.
Not depending on onDomReady or onLoad implementations solves a lot of issues.
Very interesting question. You might need to re-trigger the event/function when the page gets focus, or something similar. you might also need to keep a flag variable to track whether an 'event re-triggering' is in order.

Categories

Resources