In a part of my website I have last minute information, which should show up on ever page.
To do this I have a file named "LM_overzicht.html" which I load and display in a div like this:
$(document).ready(function(){
$("#LM2").load("LM_overzicht.html")
});
<div id="LM2"></div>
But when I change 'LM_overzicht.html' the changes won't show up when I refresh a page, only ctrl+F5 will do the trick.
So I put in some other tricks which I got from stackoverflow
first this part in HTML:
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>
But still it don't show the changes after a refresh.
I also tried another trick in JS
<script>
$(document).ready(function(){
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
$("#LM2").load("LM_overzicht.html")
});
</script>
But this doesn't clear the cache either. Anyone an idea how to fix this?
my site: Link to my site, where this 'last minute' part is at the bottom of the page
You could add a timestamp behind the file so it never gets cached.
For example LM_overzicht.html?t=1
So append a generated timestamp with JavaScript. Note that this way the HTML file will never get cached, which I dont recommend. If you still want to do so, you could always just append the day instead of the whole timestamp..
Example code to prevent caching:
$("#LM2").load("LM_overzicht.html?t=" + Math.floor(Date.now() / 1000));
Related
I have a link to a page. The loading is slow and on click event i show a progress bar and run a timing loop with random text. I do this with setInterval. I change the text every 8 seconds.
When the loading is completed, the browser shows the new page.
I don't clear Interval because i think the new page doesn't share anything with the previous page.
But, if i click on the previous button on Firefox, it seems to remember the there was an intervarl and it runs it again.
In Chrome, the prevoius button seems to reload the page and the interval there isn't.
Why Firefox has this behavoiur?
You can see the page here:
http://www.demo.tinnservice.com:8090/
I set the interval on click to "Ricerca Avanzata"
This is the html tag
<a class="linkSlow" data-action="archivio" href="/archivio">Ricerca avanzata</a>
This is the javascript code:
function smokeInTheEyes(element){
$("body").css("position","relative");
$("#wait-overlay").addClass("in");
var frasi=frasiObj[element.data("action")];
var i=0;
setTimeout(function(){$("#frase").text(frasi[i]).show("400");},1000)
var timer=setInterval(function(){
i+=1;
console.log(i);
if(i==frasi.length){i=0;}
$("#frase").hide("400",function(){$("#frase").text(frasi[i]).show("400")});
}, 8000);
}
$(".linkSlow").click(function(e){
smokeInTheEyes($(this));
});
PS: Frasi is an object with two or more array of strings. The data-action attribute on the clicked tag tell me which array i use to display the random text
Possible ducplicate:
Force Firefox to Reload Page on Back Button
This is the accepted answer created by jknair:
add this between your HEAD tags
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
So I'm testing this ephemeral images functionality in an HTML document (a la Snapchat).
My images are visible for X seconds, after which the page reloads and the displayed images are gone. Sidestepping the myriad ways someone can save an image like that, I'm squarely focused on the refresh functionality at the moment.
My JS code to refresh the page is as follows:
<script>
window.setTimeout(function () {
window.location = "example.com/page.html?nocache=" + (new Date()).getTime();
}, 5000); // refresh/redirect after 5 seconds.
</script>
I've written code that destroys the image after a single refresh - so the above trigger works perfectly. But the problem is the back button on the browser. If you press it, you simply get to see the image again. Game over!
I've already included the following meta tags in my HTML document, but they're not helping:
<meta http-equiv="Cache-Control" content="max-age=0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
Is there any way to ensure the browser back button is removed from the equation, or its effect neutralized? Please advise.
Don't refresh the page, instead use simple DOM manipulation to remove the image. If you have jQuery loaded, you can easily do it like so:
<script>
window.setTimeout(function () {
$( 'img' ).remove();
}, 5000); // refresh/redirect after 5 seconds.
</script>
(You'll want to use a more specific selector if you have more than one image on the page)
To load a new image in this context, you'll need to use an AJAX request, and set a new timer. But this will cause the back button to not bring the image back.
I am facing a problem that I am sure is pretty common. I found many solutions to this problem, and they all have their pros and cons. I'll post what I found here (which I believe will be useful to others), and I hope you'll point me in the right direction.
Essentially, this is my scenario:
I have a webpage in PHP: http://example.com/page_with_content_a_or_b.php.
This page returns Content A when no POST parameters are specified, and Content B if there are.
Assume a user connects to my page typing the previous URL in her browser (a GET request).
My server returns the page with Content A.
The user's web browser, via JavaScript, decides to replace Content A with Content B.
The question: How does the JavaScript replace the contents?
Well, as I've said, I've been looking for different solutions, but none seems perfect.
In order to discuss each possible solution, let me introduce you the resulting HTML code of each version:
HTML of Content A
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_A.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content A</p>
<script type="text/javascript" src="content-b-loader.js"></script>
</body>
</html>
HTML of Content B
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_B.css">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="gallery-animator.js"></script>
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p>Content B</p>
</body>
</html>
Differences between both versions
As you can see, in the example both versions are quite similar, but not identical. In general, these are the differences I might encounter:
All or some or none imported stylesheets may be different.
All or some or none imported javascripts may be different.
There might be differences with inline stylesheets and/or javascripts.
The content is different, but it may differ a little bit only or be completely different.
Content B does not includes the script for loading itself (last script in Content A).
Possible Solutions
Replacing Content with document.open(), document.write(), and document.close()
The first solution I implemented is the following:
content-b-loader.js (option 1)
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
document.open();
document.write(html);
document.close();
}
});
});
Apparently, the solution works properly. However, there are situations in which I have problems. In my example, for instance, both contents load a script named gallery-animator.js. Assuming this script is the following:
gallery-animator.js
var galleryInterval = setInterval(function() {
// Fade out current image and fade in the next one
$("body > div.gallery > img")...
}, 5000);
after executing the script in content-b-loader.js there are two timeouts animating the gallery. As a result, the animation looks like a mess (two images moving at the same time, or not working at all).
It looks like the sequence document.open(), document.write(html), and document.close() does not stop and replace the original scripts.
Redirecting with POST data (using a form)
Another solution is doing a redirection described in this previous question. The solution works like a charm: on the one hand, I load the URL I need to load with the required POST data, which means I'll get Content B, and on the other hand, Content B is loaded in a "new page", which means that the scripts loaded by Content A are no longer there.
The problem here? If I refresh the page with Content B, I get a warning stating that "POST data is about to be resubmitted". This is undesirable, because it looks confusing for the user (I don't want her to know she had been redirected to a new page).
I know there's a solution called PRG (Post-Redirect-Get) which avoids this particular issue. However, it requires Content B to be accessible using a GET request (using GET params or COOKIES, neither of which I can use).
Using iframes
The last solution I've found is also interesting. Basically, it hides (or empties) the body from Content A, adds an iframe in the page, and loads Content B inside it:
content-b-loader.js (option 3)
$(document).ready(function() {
$.ajax({
type: 'POST',
url: window.location.href,
data: { load_content_b: 'true' },
success: function( html ) {
$("body").css('', ''); // Remove all paddings and margins
$("body").empty();
$("body")append('<iframe id="content" seamless="seamless"' +
'src="anchor.html"></iframe>');
// Initialize vars in anchor.html and call the redirect functions
document.getElementById('content').contentWindow.url = window.location.href;
document.getElementById('content').contentWindow.options = {
load_content_b: 'true'
};
document.getElementById('content').contentWindow.redirect();
}
});
});
anchor.html
This page implements the second solution (it uses a POST redirect).
<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.redirect.min.js"></script>
<script type="text/javascript">
var url;
var options;
function redirect(){
$().redirect(url, options, 'POST');
}
</script>
</head>
<body></body>
</html>
By making the iframe as big as the window view, I can show the alternative content. If the user refreshes the webpage, the page that is refreshed is the "container" page (the one that originally had Content A), so no warnings appear at all.
The problems I am facing with this solution, however, are:
Users can disable iframes. How do I detect whether iframes are enabled or disabled?
When the user clicks a link in the frame (or submits a form), the "new page" is opened inside the iframe. This is not what I want: I want it to be opened in the main window. How do I do this? I know that there is the base directive for links... but what about forms? And JavaScript code that performs a redirection?
Does everything work properly inside iframes? Responsive themes, javascripts, ... As far as I can tell, they do, but I ignore whether users can limit what iframes can do.
TL;DR - Conclusions
I have a page http://example.com/page_with_content_a_or_b.php. The page returns Content A when accessed using a GET request, and returns Content B when accessed using POST. When user types the URL, she gets Content A, and Content B is loaded using JavaScript.
All solutions entail problems:
With document.open(), document.write(), document.close(), scripts get messed.
With POST redirections, refreshing the page popups a warning
With iframes, they are not always available, and I am somehow "stucked" inside them.
Any ideas? Am I missing something? Is there a preferred way to do what I'm trying to do?
Thank you very much!
There's a hacky fix for the problem with messy script behavior in your first solution. Assuming that the script-related problem only occurs when using timeouts (I don't know if there are other scenarios in which things can go wrong....), there's an easy way to clear all timeouts. Just add this code:
var id = window.setTimeout(function() {}, 0);
while (id--)
window.clearTimeout(id);
A POST request should do things which change or affect data. Thus it makes sense to prevent the user from refreshing and that should be desirable behavior, I am confused whether you're doing an actual post request or otherwise why is redirecting to a POST page is so problematic?
Either way, regarding your <iframe> solution, let me give some suggestions. "Disabling iframes" is indeed technically possible on some browsers, but to do such a thing you have to either dive in about:config or very deep in the IE menu and it's entirely impossible on Chrome by default. So yeah, truth be said, I would not concern myself with that whatsoever, just like nowadays most sites do not concern themselves with users who disable javascript (any user with disabled iframes will probably have javascript disabled as well btw), simply because it's too rare to concern yourself with and it's one of those choices where you have to face the consequences yourself. Now, I was planning on directing you to the <base> tag as well, just realizing now that you already mentioned it in your post. Either way, the tag will work for forms as well, but not for javascript 'links'.
All in all I would advice you to rethink whether the page should be POST, if so, then you should just go with the warning and otherwise rework it to be just another GET page.
I guess I'm missing something, because I don't clearly understand what do you mean by "The user's web browser, via JavaScript, decides to replace Content A with Content B", but:
If you know in advance the parameters of the elements whose content you'd like to replace, wouldn't a simple case by case replacement work?
<html>
<head>
<link rel="stylesheet" type="text/css" href="style_A.css">
</head>
<body>
<div class="gallery"><!-- images here --></div>
<p class="content">Content A</p>
</body>
<!-- This could be content-b-loader.js -->
<script>
var $stylesheet = document.getElementsByTagName('link')[0];
$content = document.querySelectorAll('.content')[0];
if ( $stylesheet && $content ) {
if ( $stylesheet.getAttribute('href') == 'style_A.css' ) {
$stylesheet.setAttribute('href', 'style_B.css');
}
$content.innerHTML = 'Content B';
}
</script>
</html>
The client I am working for is trying to make it so that his page never has to reload. Instead he just wants to use AJAX. Now I realize that the way im doing it is not a very efficient way to do it but it is the easiest and you would understand why if you would see his site..
I'm trying to get it to work so that AJAX will refresh only parts of the page or the whole page.
My code is:
<!doctype html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script>
function refresh (update) {
$.get(location.href, function (data) {
console.log(data);
var EL = $(data).find(update);
var HTML = $('<div>').append(EL.clone()).html()
alert(HTML);
$(update).replaceWith(HTML);
});
}
</script>
</head>
<body>
<div style="font-size: 64px;">The current timestamp is <b class="time"><?php echo rand(999, 9999999); ?></b></div>
<br><br>
<button onclick="refresh('.time')">Refresh Time</button>
</body>
</html>
When you first load the page PHP generates a random number. Hitting the refresh button is suppose to refresh this number. However, the same number stays there. The request returns the exact same page instead of return a page with a new number.
And again, people note that I know this is not a very efficient way to do this, but its the way i'm trying to get it to work
Am I doing something wrong? (besides requesting the whole page when only actually using part)
EDIT
You can try it out here: http://methods.x10.mx/projects/refreshPageParts.php
Change your call to this, to break the caching:
function refresh (update) {
$.ajax({
type: "get",
cache: false,
url: location.href,
success: function (data) {
$(update).replaceWith($(data).find(update));
}
});
}
See the notes on caching in the documentation: http://api.jquery.com/jQuery.ajax/
By default, requests are always issued, but the browser may serve results out of its cache. To disallow use of the cached results, set cache to false. To cause the request to report failure if the asset has not been modified since the last request, set ifModified to true.
I tested your example on my local wamp stack and it is working fine!
btw: you forgot semicolon after the following line (It is not necessary though)
var HTML = $('<div>').append(EL.clone()).html();
EDIT: your code is working... also on the url you provided. The strange thing is you have to wait a few minutes before it is working. So when you visit the page and press the button, the time won't be updated... however if you wait few minutes it will... only once then you have to wait again. I bet your server is caching the page. So your problem is server side... disable the cache and it will work!!
EDIT:
you also could try to make the get url dynamic with a dummy parameter like so
http://methods.x10.mx/projects/refreshPageParts.php?v=dummy
maybe you don't have to make dummy dynamic, it might work with a static variable also. i'm curious, let me know ;-)
I'm sure I'm missing something pretty basic, but I have just started to get myself up to speed on jQuery and Javascript programming. Previously I was doing server side programming with PHP.
I'm now in the middle of creating a prototype for HTML5 webapp, where I would like to have different screens. Now with PHP that was pretty easy, I could just used server side templates like Smarty and be done with it.
However to make my app more webapp like, I would like to dynamically change between screens without having to reload the window.
I have looked into several options that might be anwsers to my question, but I'm not sure whether I'm on the right track.
I have checked for example JsRender, JsViews or even the pure jquery load command.
But what I'm not sure is whether these things would allow me to have something like this:
HEADER_PART
MAIN_CONTENT
FOOTER_PART (also contains links to common JS files that I use)
I would like to dynamically update the MAIN_CONTENT part. Currently my application is only one page, and all my custom logic that belongs to that page is in one JS file. In this JS file, I use a simple $(function() { ... to load my page, so whenever it gets loaded, parts of my page get updated asyncronously. This is fine, since all my blocks in this certain page would have to be loaded when that one page gets loaded.
But what if I have a link, like main.html#otherscreen, and when I click that screen, I would like to change my MAIN_CONTENT and also run another page load specific JS that handles blocks on that other screen, not the first page?
I know I could still use probably server side templating and load my pages using AJAX requrests, but again, not sure whether that is the right approach.
Could you please enlighten me? :)
Thanks & best regards,
Bence
Check out jQuery.load(). Using this function you can dynamically load content into a div on the page, which is what I think you want to do. Just find the div on the page you want to load content into and call
$('#mydiv').load(url, data, function(response){
//do something once it's done.
});
Per your comments...
This is actually very easy. .load() should replace the content in the div (I think. If not, just call .empty() first). Of course you could get fancy and add effects, like
function changePages(url) {
$('#mydiv').fadeOut('fast', function() {
$(this).load(url, function(response){
$('#mydiv').fadeIn('fast');
});
});
}
To handle things like the hash in the URL, in your click event you have to make sure you first call e.preventDefault():
$('#mylink').click(function(e){
e.preventDefault(); //e is a jquery event object
var link = $(this);
var hash = link.attr('href'); // get the hashtag if the href is '#something'
changePages(someUrl + hash);
});
For dynamic loading of data into the page without changing your header and footer you should use jQuery's AJAX function. It allows you to post requests to the server and receive data back without reloading the page. A simple example would be something like:
<html>
<head>
<title>Example</title>
<!-- Assuming jQuery is already referenced -->
<script type="text/javascript">
$('span.buttonish').click(function(){
$.ajax({
// The URL can be a file or a PHP script of your choosing
// it can also be pure HTML without the <html> tags as they
// are already in your file
url: 'path/to/the/file/that/return/data',
success: function(receivedData) {
// The received data is the content of the file or the return
// data of the script and you can use it as you would with any data
$('#content').html(receivedData);
}
});
});
</script>
</head>
<body>
<div id="header">
<!-- Something -->
</div>
<div id="content">
<span class="buttonish">Click me to change the text... </span>
</div>
</div id="footer">
<!-- Something -->
</div>
</body>
<html>