How to detect back button and new window? - javascript

I've no doubt that these are probably documented on the internet somewhere and indexed by Google - but after wading through pages and pages of links to discussions about disabling the functionality I thought I'd ask to see if anyone can give useful answers about merely detecting their usage.
The method described in one of the better articles on disabling the back button only works by creating a page transition - so not much use for detection.
The presence of window.history.next might provide a mechanism for detecting the back button - but how widely supported is it? Does it require unusual privileges?
Jonathan's answer to this post looks promising - but pre-supposes that I can set the window name on the first landing - I guess I could use the absence of a cookie to detect first hit. Any other ideas?
TIA

I wrote some code a while back. The script was never fully tested, but you should be able to pull out some techniques to get the same effect as to detect the back button from it.
http://pastebin.no/32fx

Use sessionStorage/localStorage.
if (!sessionStorage.hasBeenHereBefore) sessionStorage.hasBeenHereBefore = true;
else {
// Code to run if they've been here before.
}
If you use sessionStorage, then if they close the browser and come back, it will seem like the first time, but if you use localStorage then it'll stay forever.
You might try looking for some secret events like:
window.addEventListener('historyback', function () {}, false);
window.addEventListener('navigateback', function () {}, false);
window.addEventListener('returntopage', function () {}, false);

Related

How can I find the code that's refreshing the page?

How can I find the specific code that's causing a web page to auto-refresh?
I've looked through the source for an HTML meta-refresh, to no avail. I also can't find any Javascript "reload" in the main page, leading me to think it's perhaps externally loaded through a link javascript file.
How would a "pro" track this down, like through Firebug (or other debugger)?
Note:
I'm more interested in the process of being able to debug and track down something like this, rather than a "catch-all" solution that will stop it cold (such as disabling the Firefox-wide ability for pages to auto-refresh themselves).
The problem is most likely in a javascript file. Go through them looking for the below:
1) Look for anything that can be used to change the URL/location, redirect, or cause browser to go back:
window.location.href
window.history.back(-1)
window.navigate(”example.html”);
self.location=”top.htm”;
top.location=”error.jsp”;
2) Look for timers such as:
setTimeout()
setInterval()
3) Look for broken selectors. You may have click event handlers attached to whole DIVs, or even the whole document by accident.
There is no straightway to find the source of the refresh in javascript. Try #Steve Papa's tips on your code.Incase you want to prevent the refresh and see in the console if you can find any useful info.
To stop the refresh, use onbeforeunload event. The event object passed to the event has lot of info, but I couldnt find anything which points to the trigger. Add a breakpoint on closeIt(e), and look for clues in global variables or call stack(which i dont think will be of much use here).
function closeIt(){
return "Any string value here forces a dialog box to \n" +
"appear before closing the window.";
}
window.onbeforeunload = function(e){
closeIt(e); //add a breakpoint here.
}
setTimeout(function(){location.reload()},2000);
http://jsfiddle.net/Gjuhm/4/

Detect if the ctrl button was pressed

I want to prevent users from printing a page
I thought I would set the screen to not include the toolbars, and prevent right clicks, and prevent Ctrl+ P, and the Print Screen button.
Can this be done?
Is there any good code out there for this? I have searched quite a bit so far, but not much luck. I know this isn't foolproof, but it will prevent some users from copying or printing.
You can't do this...you can't disable the user's ability to print, nor should you try.
Ctrl+P is the way a programmer prints, File > Print (depending on browser) is the way the typical user does...so this wouldn't even disable the most common method. In addition, any decent programmer can get around this anyway, so it effectively doesn't stop anyone.
Any data you get to a user, displayed or not, they can see, copy, print, etc...there's nothing you can do to prevent this, definitely not 100%. If this is one of your requirements...you should be asking if a website is the best way to deliver this data.
By doing that, you will annoy legitimate users, and if you think a serious copyright violator uses a regular browser (whose printing function you can disable), then you're very mistaken.
On the one hand information wants to be expensive, because it's so valuable. The right information in the right place just changes your life. On the other hand, information wants to be free, because the cost of getting it out is getting lower and lower all the time. So you have these two fighting against each other. source
Also:
Information Wants To Be Free, and Code Wants To Be Wrong.
I agree with the answers above.
Users will always find a way around this,
- A computer is not secure for copyrighted material and will never be.
you need to take that into account.
If you'd want to make it so that regular computer users can't do it this would help:
Create an application that loads and displays the document after input of a keycode that you supply (check via webserver).
the application does not have printing functions since you did not put them in
register a global keyhook to blank the document if the user presses "printscreen" and show a copyright warning
A couple of years ago, I built an exam system where one of the requirements was to make it hard for people to print the exams. Removing the print functionality is as we know, impossible (unless you do some changes in the browser software). What you can do is to make it harder for non-technical people to print the page. E.g. Use CSS to blank the page when it goes to the printer:
<style type="text/css">
#media print {
body { display:none }
}
</style>
The following jQuery script will prevent copy&paste in some browsers:
$(document).ready(function () {
$(document).bind('copy paste', function (e) {
e.preventDefault();
});
});
the #Nick Craver answer is right, you can't prevent it but anyways if you want to detect the key combination using mootools you have the keyboard class that let you define key combinations and add events to it:
http://mootools.net/docs/more/Interface/Keyboard
that maybe will be useful to display a warning or something like that :)
You could so with jQuery for example. However think of this: a browser runs on a client pc which is owned by someone. That person should be in control of what happens on his/her device. It's not up to you to start putting scripts to get rid of standard functionality the enduser might want to use.
If you don't want something to be printed then don't show it on a public place. If it's confidential, treat it as such.
Grz, Kris.
Take this into account. I agree with the other answers and present another way around this. All the user must do is take a screenshot, which involves the application layer of the operating system, and one of which you cannot even hope to change. On Ubuntu, it's even in the user's main menu to do this.
<script type="text/javascript">
function detectspecialkeys(e){
var evtobj=window.event? event : e
if (evtobj.altKey)
alert("you pressed 'Ctrl'");
evtobj.preventDefault();
}
document.onkeypress=detectspecialkeys
</script>

Is there a way to tell when a div has been added to an element?

Say I have a third party Twitter widget on a page which keeps updating whenever there is a new tweet. Is there some way to figure out when a new div has been added to this widget? Is there an event or something I can hook onto (on maybe the widgets parent div)?
If there isn't, how do I do this? Maybe hook onto the ajax calls the widget is making? How do I do that? It seems possible as firebug seems to be doing this but I can't tell how.
If you're using any kind of modern browser, you can use the DOM Mutation Events to listen for node changes. From the description of your question you're probably looking for DOMNodeInserted. If you must you can use a horrible setTimeout() hack, but in general it's better to wait for events than spin around waiting for something to happen.
Heck here is some example code because I am bored:
var widget = document.getElementById('mywidget');
widget.addEventListener('DOMNodeInserted', function (e) {
if (e.target.nodeName !== 'DIV') return;
// do some other code here
}, false);
Don't ktow if this is a good solution but you can periodicaly compare content of this div.
Giving the simplest answer first: I would suggest checking if the div exists after a second (time depending on many factors - I'm sure you understand the time specifics for your site). When adding a new element (such as your twitter widget) it's important to understand that each element (in your case, "a widget") comes with certain specifications which can have major differences compared to similar (on the surface similar) "widgets"
For a short answer: "It depends on the third party widget"
For the medium answer: "If you can look at how the widget is created, you can probably find a way to 'talk to it'"
For the longer answer: "It's actually not very difficult to create something to communicate with Twitter, so if that's what you want to learn I would suggest being more specific."
Hope SOMETHING OF THIS HELPS...
edit: Knowing nothing about the widget, I would probably set an interval to make requests from client to server, either by using javascript:setInterval() or setTimeout()... If I had time/resources, I would prefer a solution where you understand both Twitter and the widget though (saves time in the future if you want to think about what you've done)...

Save the anchor in the ie6 history

I have a site with anchor navigation (like gmail, when the anchor value changes a new content for a page is loaded with ajax). In Firefox, when I change the anchor (with js or with a page) a new item in the history is created and works perfectly. But in IE6 it doesn't stores this new item and the back button doesn't work as expected.
Is there anyway to add this new item using javascript?
This is possible because gmail does it but I don't know how it does it.
I've done a lot of work with history and using the hash. Almost all of the existing history plugins have some sort of gap in them. The one I've used that's pretty close to perfect is this one which is a jQuery plugin:
http://www.mikage.to/jquery/jquery.history.js
It was updated in March of this year handles IE 8 issues and it also deals with IE6 pretty successfully. One thing I've noticed is that IE really hates having ? in the hash after the #. It stops properly handling the hash when the ? is present. Even this one I think needs a little patch for the ?, I really need to send that along to Mikage. The way to handle this is instead of using location.hash in the plugin when referencing the hash, use this function:
function getHash(loc) {
loc = loc.toString();
if (loc.indexOf("#") != -1)
return loc.substring(loc.indexOf("#"));
else return "";
}
So in those spots where you need the hash, pass location the to function...
getHash(location)
...instead of using location.href. But note that for IE, because it's using the iframe, you want to use iframe.location instead.
getHash(iframe.location)
Yahoo's Bug
You can see that Yahoo doesn't gracefully handle ?'s in IE when looking at this URL:
http://developer.yahoo.com/yui/examples/history/history-tabview.html#tabview=tab1?7236471234
It should just ignore the non-existent module, (which it does for other names which have no ?'s in them). But it raises a JavaScript error when a ? is in the URL.
(I will extend this list in a moment)
Really Simply History
Frankly, it's primary issue seems to be it's gone dormant. I've experienced this issue and just didn't want to dig through it:
Also, even though no changes appear to
take place on the page while I travel
backward through the history, the back
functionality will return once I hit
the pages that I had been navigating
before the one using RSH. So, if I
clicked on four links in the RSH page,
back functionality will return after
I have clicked on the back button four
times. I hope that makes sense.
I think you may have a different problem. IE6 certainly handles # links in history as it should for me on any given test page, so I believe either you have broken this in some way or you have a bug with your particular version of IE.
I suggest you try a few different copies and versions of IE6 on other machines to rule out the latter, and then try simplifying your code and rebuilding it to see if and when the problem appears. Turning off JS may (html depending) be a fast way to test this.
If all else fails I suggest you look at Really Simple History which (last time I checked) solves almost all JS/history problems you can throw at it.
Yahoo has a history manager too.

How can I monitor users clicking on links via Javascript?

I've been tasked with determining if it's possible to detect link clicks with javascript.
I'm aware of the onclick attribute, which gets me part of the way there. Other then that, I don't know what the best approach is. I've already told my boss that it will likely involve some form of ajax, which probably involves a big library, which is not acceptable.
Is there any other way then to use ajax, or anyway to use ajax that won't add a lot of time?
Edit: He wants to be able to tell how many times users use the links on the homepage of the site. Unfortunately, we can't do a slick server side solution because nearly all of the pages on the site are just plain html . I would love to convert all the pages to php or some other alternative and just take note of HTTP_REFERRER data, but that's not currently possible.
We're already using Google analytics; it doesn't record the referrer data.
Edit again: It turns out that my boss hadn't seen the overlay, and I assumed he clicked through all the tabs. Upon my investigation, initially they were all reporting zero clicks, but I discovered that we had the old version of google's analytics blurb in place. A quick upgrade to the new hotness one and the problem is solved.
Thanks to all the responses.
Actually, Google Analytics does track this data. If you go to the Content Overview page of your report, there is a link for Site Overlay. This will show you your website overlaid with the number of clicks on each link on the page.
site overlay example http://okay-plus.com/dropbox/img/site_overlay.jpg
If this is for data collection about website usage, have you considered Google Analytics instead?
Wont go into discussion about whether this is a good idea or not, but here is some code that does what your header asks.
As you put it yourself, the onclick event is one way to go. You need to create a script that loops through the a tags and assigns an onclick event to them. Something like this:
<script type="text/javascript">
window.onload = function() {
var a = document.getElementsByTagName("a");
for(var i=0; i < a.length; i++ ){
a[i].onclick = function() { alert("link clicked"); };
}
}
</script>
If you want to tell the server about the click you would need an AJAX call instead of the alert :) That snippet goes into the head section to work.
Another way to go about this is to listen on the general window.onclick event and trace the object being clicked, if it's an a tag you can execute whatever code you wish.
jQuery.min.js is 30k in size or under. That's not big.
Why does your boss want to monitor link clicking anyway? If it's to URLs on your own site then you should be able to get that from access logs or Google Analytics anyway (or some more useful variant of that information).
If you end up using jQuery (as one of the posters here have recommended) you can intercept all link fairly easily. For example, if you wanted to count how many times each link was clicked (indexed by id), you could code something like this:
var clickCount = [];
$('a').click(function() { clickCount[$(this).attr("id")]++; return true; });
For some reason, if you cannot use google analytics, try handling the window.onclick event and from the event object you can read the src element. This would tell you the object on which click event is triggered. (I believe click will be triggered for both keyboard and mouse.
Sample code written only for IE. If you need other browsers, you may have to modify the code
document.onclick = function()
{
alert(window.event.srcElement.id);
}
In addition to Google Analytics, you might wish to check out ClickTale. It offers site overlay plus quite a few features Google doesn't.
By the way, you can also tag up your external links and get GA to track them as well:
"How do I manually track clicks on outbound links?"
Another great tool you might want to check out is http://mouseflow.com. Mouse tracking, video playback and heatmaps.
in RXJS:
import { fromEvent } from 'rxjs';
const source = fromEvent(document, 'click').pipe(
filter(value => (value as any).toElement.localName === 'a'),
map(value => (value as any).toElement)
).subscribe(value => {
track('Clicked Outbound Link', {link: value.href})
})

Categories