I have a link which when clicked redirects the user to the same page except with additional parameters:
<a id="lnkExportToPDF" href="javascript:void(0)">Export</a>
$('#lnkExportToPDF').click(function (e) {
e.preventDefault();
window.location.href = path + 'users/export/' + parm1 + '/' + parm2;
});
On the server side I handle it by checking for "export" in the request path, and if it's found I write a PDF file to the response:
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.Clear();
response.AddHeader("Content-Type", "application/pdf");
response.AddHeader("Content-Disposition", String.Format("attachment; filename=" + filename + ".pdf; size={0}", buffer.Length.ToString()));
response.BinaryWrite(buffer);
response.End();
Everything works and the user can download the file, but any additional actions by the user that uses the loader.gif which is on the page shows an unanimated loader.
What could be causing this to happen? Is there any way to refresh/reload the page/javascript after the response is complete?
edit: I've found a useful JS tool here: http://fgnass.github.io/spin.js/ but I'd prefer not to use it unless absolutely necessary
edit2: I also tried using a generic handler (.ashx) to handle the request (ie. changing the href to point to the handler), but as soon as the page redirects and the file is written, same thing happens
edit3: The problem is only happening in Firefox so far. I've tried Chrome and IE and the gif stays animated in those browsers. (latest versions of each)
edit4: If I use an iframe with the src as the image it solves the issue, but it's very hacky and the style of it looks different across all browsers with regards to centering/padding/margins.
edit5: Yeah. If I inspect the frozen gif with firebug it magically unfreezes itself.
I managed to recreate the problem in firefox and I really can't find a way to "unfreeze" the gif. When I added a completely different file after a download and that too was frozen I gave up with that approach.
What I did instead was to test different ways to trigger the download. I found no window.location solutions that worked, what did work though was this:
window.open(path + 'users/export/' + parm1 + '/' + parm2);
window.open opens a new tab and downloads the file through that instead of the current tab as window.location does. It will return to the current tab as soon as the download starts.
Edit
You could also use a hidden iframe:
var iframe = document.getElementById('iframe');
iframe.src = path + 'users/export/' + parm1 + '/' + parm2;
I confirm that I have the same behavior with firefox, and the first that come to my mind is to use SetTimeOut but still the same behavior, so on firefox for some reason, this window.location.href is also call the "Stop" on browser, that this cause the gif animation to stop.
So what I found and you can solve your issue, that this is not happends on simple links.
And if you change your code you can archive the same effect with a link.
So change this
$('#lnkExportToPDF').click(function (e) {
e.preventDefault();
window.location.href = "page.aspx";
});
to something like this
$('#lnkExportToPDF').attr("href", "page.aspx");
and you have the same results, and gif will still moving.
Here is the fiddle test.
On the test I add to move to paypal, because is slow moving and you can see the animation stop or not, also pp not let show on iframe, so on example you stay on example and not load the page.
When you click on this example, the issue is appears only on firefox !
http://jsfiddle.net/hn7S9/4/
One other issue that I think is that if you need to make your parametres to the next page on click, you probably need to redesign that and fix them before your click.
This is possible because for sure is not depends on the last click on the dynamic create link. So make the link with their parametres before the click.
You could try an asynchronous approach on the click to allow the browser to parse the event queue after the click has initiated:
$('#lnkExportToPDF').click(function (e) {
e.preventDefault();
setTimout(function() {
window.location.href = path + 'users/export/' + parm1 + '/' + parm2;
}, 20);
});
How about allowing the link to actually fire, but opening it in a new tab?
That shouldn't interrupt anything about the gif, and is semantically fine, other than I guess it would leave a tab open. You could get rid of the content-disposition, and allow the browser /user to decide what to do with it though.
<a id="lnkExportToPDF" target="_blank">Export</a>
$('#lnkExportToPDF').click(function (e) {
$(this).attr("href", path + 'users/export/' + parm1 + '/' + parm2);
});
Instead of setting the window.location.href, you can use a form with method="get" and submit it. This form could either be coded into your HTML or created dynamically. See this Answer:
https://stackoverflow.com/a/21742326/1614903
Here's my solution. It's faster and easier than any fix or workaround I've found. Just open the problem page in Chrome. Chrome has it's own problems, but this isn't one of them. Whenever I encounter a page full of gifs that causes Firefox to freeze, I just copy the URL, close the tab, open Chrome, and paste in the URL. I works every time! :o)
Related
I use JQwidgets ,, I use to print data onclick print-button
as code :
$("#print").click(function () {
var gridContent = $("#jqxgrid").jqxGrid('exportdata', 'html');
var newWindow = window.open('', '', 'width=800, height=500'),
document = newWindow.document.open(),
pageContent =
'<!DOCTYPE html>\n' +
'<html>\n' +
'<head>\n' +
'<meta charset="utf-8" />\n' +
'<title>jQWidgets Grid</title>\n' +
'</head>\n' +
'<body>\n' + gridContent + '\n</body>\n</html>';
document.write(pageContent);
document.close();
newWindow.print();
});
When I close printing-widow(not continue printing), I can't use the grid-scroll (on chrome)..
google-chrome Version 34.0.1847.131 m
This worked fine on Firefox and IE..
How to fix the scroll after closing printing-window on chrome
Fiddle-Demo
It looks like you're not the only one with this issue.
I understand that your code is already setup and you want to run with what you have, but unless someone comes up with a hack or Google decided to fix what is clearly a bug, I think you need to re-think how you are approaching this issue.
If chromeless windows were an option, or if the print dialogue were a modal then you could pull this off with the current strategy, but neither of those options are possible in Chrome. Even if you were able to get around this scrolling issue somehow you're still left with a less than desirable UX problem in that if the user hits "cancel" in the print dialogue then they are left with a still open blank window.
Here is a JS fiddle to demonstrate that you need to change your approach: DEMO
You can see from this demonstration that even if we run a completely separate script from within the new window by passing it as plain text in the content object, it still causes the same issue. This means to me that this is a parent/child type of a relationship that is not easily circumvented with JS.
I recommend 2 alternative possible solutions:
Option1:
<input type="button" value="Print" onclick="window.print(); return false;" />
This triggers a full screen print dialogue that can't be closed from the "Windows Close Button." That way you can avoid the issue all together. Then you can use a combination of JS and Print Styles to target and isolate the information you want to print. I know it's more work but I think may be the better cross-platform solution.
This option is more brute force and simplistic in nature (and you have already commented that you know this but I'm leaving it up because it's still an option).
DEMO
Option2:
User clicks on a link/button that opens a new tab/window
In the same function the data from your table gets loaded into a JSON Object
The JSON object is loaded into a print template in the new tab/window
the template initiates the print function
By taking these actions, I think you will have disassociated the JS instance enough that the new tab will not affect the initiating script.
This is a browser bug - you'd have to find some sort of hack to fix it.
Doesn't sound like you want to put the print dialog code elsewhere thus not affecting your scroll bar. That is the obvious solution but it sounds like you can't do that.
Here's what I would do: Wait until someone has triggered the problematic condition, then put an event listener on the scroll event. when it happens... go ahead and reload the page.
Simple, easy, fun.
var needToReload = false;
$("#print").click(function () {
... as you have
needToReload = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
}
$('#contentjqxgrid').scroll(function () {
if (needToReload) {
window.location.reload();
}
});
$("#jqxscrollbar").jqxScrollBar({
width: 5,
height:180,
theme:'energyblue',
vertical:true
});
$("#jqxscrollbar1").jqxScrollBar({
width: 300,
height:5,
theme:'energyblue'
});
Look at jsfiddle: http://jsfiddle.net/8PtUX/6/
I just updated to chrome version 32.0.1700.76 m and I am now noticing that hashchange seem to act weird. sometimes it work, sometimes it doesn't.
I have the following code on my homepage and I haven't changed the code in a few months. worked fine a few days ago(before I updated to latest chrome version):
$(window).on('hashchange', function () {
var page = location.hash.slice(1);
$('[data-page]').addClass('hidden');
$('[data-page=' + page + ']').css('z-index', '0');
$('#1st-row').children().eq(0).css('z-index', '1');
$('#1st-row').children().eq(1).css('margin-left', '-200px');
$('[data-page=' + page + ']').removeClass('hidden');
$('#1st-row').children().eq(1).animate(
{ 'margin-left':'0px' }, 1000);
$(':checkbox').checkbox('check');
$('#debug').attr('value', 'true');
});
I figured something wasn't working as it should when I redesigned my site so i changed it a bit:
$(window).on('hashchange', function () {
var page = location.hash.slice(1);
$('[data-page=' + page + ']').slideDown();
});
but it's still not working.
I have to reload the page several times, go to the site again(ctrl+l -> enter), reload a few more times and then it magically works. it won't work a second time though... I have to refresh and reload the page/site a few more times before it decides to let hashchange work.
you can test it at lingonsorbet.se.
just add #advanced to the url and a box should appear to the right. works fine in firefox and ie.
am I doing something wrong or has anyone else run into this too?
hashchange is not fired on page load
The hashchange event is only triggered when you manually change the hash or when you click an in-page anchor link (Advanced). Reloading a page without changing the hash does not trigger hashchange.
You should refactor your hash-checking code into a new function and execute it
on the hashchange event
on page load.
Consider this code:
function changeLayoutByHash() {
var page = location.hash.slice(1);
$('[data-page=' + page + ']').slideDown();
// etc.
}
$(window).bind('hashchange', changeLayoutByHash );
$(window).ready( changeLayoutByHash );
As per your question, I don't see inconsistencies in the way Chrome handles this.
If you keep reloading example.com#advanced, hashchange will not be fired. Only when you change the hash to example.com#advance (delete a character), it's registered as a changed hash.
Debugging
To find out whether or not certain events are being fired, you can always write a little console.log('hashchange fired'); into your event handlers and then (with ChromeDev Tools open) see in the console what your program does.
I am having problems in redirecting page with jquery. I have a variable url which contains localhost/abc#123. When i write document.location.href = url;, the page redirects to localhost/abc leaving #123. How to resolve this issue
var url = "http://bing.com/refresh/test.html#123";
document.location.href=url
it's work fine for me in my firefox. do you have tried to debug what happen on your side. I have test this code in IE8 + firefox + chrome. I hope it's will work fine for you.
if this code doesn't work on your side then try
window.location.replace(url)
as your comment it's look like you have used Anchor so tried this one.
$("#myanchor").click(function(e){
e.preventDefault();
// redirect code here
});
Instead of linking directly to files for download on a web site we link to a page that says "thank you for downloading". The page has tracking codes on it so we know how many people have downloaded the file. The page launches the download file using the jQuery code shown which adds a short delay after the page loads before the download begins. The download location has a content disposition header so it always downloads properly in the browser leaving the "thank you for downloading" page visible. This all works well.
The problem comes if the user carries on browsing past this page and then hits back. The download fires again.
Using window.location.replace(href); didn't seem to fix it.
The issue is further complicated by the fact that the CMS delivering the page has set it to expire immediately so it's not being cached.
Suggestions for (i) ways to avoid this problem; (ii) any better ways to handle file download / thank you pages?
jQuery Code
$(document).ready(function () {
$('a.autoDownload').each(function () {
setTimeout('navigateToDownload("' + $(this).attr('href') + '")', 4000);
});
});
function navigateToDownload(href) {
document.location.href = href;
}
One possible approach would be to set a cookie via Javascript when the page first loads. Then, if that page is ever loaded again, you can check for the presence of the cookie, and if present, do not execute the auto download?
Using the Cookie plugin for jQuery as an example:
$(document).ready(function () {
$('a.autoDownload').each(function () {
var hasDownloadedThisLink = $.cookie("site." + $(this).attr('id'));
if (!hasDownloadedThisLink) {
$.cookie("site." + $(this).attr('id'), "true");
setTimeout('navigateToDownload("' + $(this).attr('href') + '")', 4000);
}
});
});
This is just an example. If you went this way, you'd have to consider how many possible download links there might be, as there is a limit on how many cookies you can set. Also notice that I used an id attribute of the links to identify them in the cookie - I figured this would be more suitable that using some form the href attribute. I also prefixed the cookie name with site..
Well there are a couple of solutions to this. Here's an example:
function navigateToDownload(href){
var e = document.createElement("iframe");
e.src=href;
e.style.display='none';
document.body.appendChild(e);
}
Other implemenatations might exist, but I doubt they're less "hacky".
Background: I have an HTML page which lets you expand certain content. As only small portions of the page need to be loaded for such an expansion, it's done via JavaScript, and not by directing to a new URL/ HTML page. However, as a bonus the user is able to permalink to such expanded sections, i.e. send someone else a URL like
http://example.com/#foobar
and have the "foobar" category be opened immediately for that other user. This works using parent.location.hash = 'foobar', so that part is fine.
Now the question: When the user closes such a category on the page, I want to empty the URL fragment again, i.e. turn http://example.com/#foobar into http://example.com/ to update the permalink display. However, doing so using parent.location.hash = '' causes a reload of the whole page (in Firefox 3, for instance), which I'd like to avoid. Using window.location.href = '/#' won't trigger a page reload, but leaves the somewhat unpretty-looking "#" sign in the URL. So is there a way in popular browsers to JavaScript-remove a URL anchor including the "#" sign without triggering a page refresh?
As others have mentioned, replaceState in HTML5 can be used to remove the URL fragment.
Here is an example:
// remove fragment as much as it can go without adding an entry in browser history:
window.location.replace("#");
// slice off the remaining '#' in HTML5:
if (typeof window.history.replaceState == 'function') {
history.replaceState({}, '', window.location.href.slice(0, -1));
}
Since you are controlling the action on the hash value, why not just use a token that means "nothing", like "#_" or "#default".
You could use the shiny new HTML5 window.history.pushState and replaceState methods, as described in ASCIIcasts 246: AJAX History State and on the GitHub blog. This lets you change the entire path (within the same origin host) not just the fragment. To try out this feature, browse around a GitHub repository with a recent browser.
Put this code on head section.
<script type="text/javascript">
var uri = window.location.toString();
if (uri.indexOf("?") > 0) {
var clean_uri = uri.substring(0, uri.indexOf("?"));
window.history.replaceState({}, document.title, clean_uri);
}
</script>
There is also another option instead of using hash,
you could use javascript: void(0);
Example: Open Div
I guess it also depends on when you need that kind of link, so you better check the following links:
How to use it: http://www.brightcherry.co.uk/scribbles/2010/04/25/javascript-how-to-remove-the-trailing-hash-in-a-url/
or check debate on what is better here: Which "href" value should I use for JavaScript links, "#" or "javascript:void(0)"?
$(document).ready(function() {
$(".lnk").click(function(e) {
e.preventDefault();
$(this).attr("href", "stripped_url_via_desired_regex");
});
});
So use
parent.location.hash = '' first
then do
window.location.href=window.location.href.slice(0, -1);
As others have said, you can't do it. Plus... seriously, as the jQuery Ajaxy author - I've deployed complete ajax websites for years now - and I can guarantee no end user has ever complained or perhaps ever even noticed that there is this hash thing going on, user's don't care as long as it works and their getting what they came for.
A proper solution though is HTML5 PushState/ReplaceState/PopState ;-) Which doesn't need the fragement-identifier anymore:
https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
For a HTML5 and HTML4 compatible project that supports this HTML5 State Functionality check out https://github.com/browserstate/History.js :-)