How to recall browser tab with previous instance on same page - javascript

I have a page with a few links.
Each link opens in a new tab.
The next time I click a given link, I want it to recall the same tab where it was previously opened.
Is it possible? How?
All pages come from the same domain.
I've seen this answer:
Check if my website is open in another tab
It seems possible to store the URIs in localStorage, for repetitions detection.
I think this technique will allow me to detect repetitions, but I can't figure out how to aim at the specific tab (activate it, bring it to the front).
I don't control the server, need to implement it in the client (via Tampermonkey).
For the curious, I work a lot with BitBucket issues.
The page with the links is the issues listing, the other pages are the individual issues.
I want to be protected from opening the same issue twice, update both versions, and have a data loss.
Additionally, each page can have two different URIs, one for viewing and the other for editing. But I think I can solve it with JS.

Recalling a Browser Tab by Name
You can first specify a name for each tab you create, by using window.open():
let newWindow = window.open(newUrl, newWindowName);
or by using target attribute in an anchor tag:
Make New Window
If you then call window.open with the name of an existing tab, that will use the existing tab. If the window by that name doesn't exist, window.open will create a new window (or tab).
MDN web docs page for Window.open
Bringing Window to the Front
Using window.open() alone may not be enough to bring the window to the front. That may be possible with a different function, window.focus(), which issues a request to bring the window to the front. Combining the two:
window.open(myUrl, myWindowName).focus();
Caution: A browser's user preference setting may still prevent focus() from bringing the window to the front, so this is not guaranteed to work. From MDN web docs:
It may fail due to user settings and the window isn't guaranteed to be frontmost before this method returns.

You can get the previous page's URL with the following:
let prevURL = document.referrer;
You can get the URLs from all open tabs with the windows.getAll() function.
From this answer - You cannot programmatically focus the browser to a specific tab due to security concerns. Consider updating the title to notify the user with document.title = {{new title}}

Related

porthole.js - how can I close a tab that I opened using window.open(), but from the new tab

I need to spawn a tab using window.open('...', '_blank');
Then, I need that tab to CLOSE ITSELF, when the user click a button (button is in the new tab).
I have control over the codebase and server of both applications.
I tried the following:
in app#1:
window.tab = window.open('http://localhost:5007', '_blank');
in app#2:
function clickedButton() {
window.opener.tab.close();
}
Unfortunately I get security exception:
Error: Blocked a frame with origin "http://localhost:5007" from accessing a cross-origin frame.
How can I get around this error? Is there anyway I can use this library to overcome this? https://github.com/ternarylabs/porthole
I am simply going to quote documentation here, just for anyone who needs a reference click W3C and MDN.
function openWin() {
myWindow = window.open("", "myWindow", "width=200, height=100"); // Opens a new window
}
function closeWin() {
myWindow.close(); // Closes the new window
}
To break it down, the open and close functions use parameters than can be very useful, such as the URL, when desiring to open or close the current window, or in your case the opened window.
A practical example would be this stack overflow question. N
I hope it helps!
EDIT
To answer the OP's edit to the question: If it is a matter of triggering an event on a window which was opened, you can on the new window have an event handler which will trigger window.close() like so:
$('#anElementId').click(function() { window.opener.$('body').trigger('theCloseEvent', anyPassedData); })
However, if you truly do have control over the new tab, because it leads to a URL whose code base you are in control of, then it is only a matter of triggering an event there that you can trigger either once the window loads, or once you click a button... like so:
HTML
<button id="close-window">Close me</button>
Javascript/jQuery:
$(document).ready(function(){
$("#close-window").click(function(){
alert("ok");
window.close();
});
});
EDIT #2
To further extend the OP's edit, I want to include here an issue that can easily be encountered when attempting to trigger the opened window to close itself.
Quoted from How can I close a browser window without receiving the “Do you want to close this window” prompt?:
Scripts are not allowed to close a window that a user opened. This is considered a security risk. Though it isn't in any standard, all browser vendors follow this (Mozilla docs). If this happens in some browsers, it's a security bug that (ideally) gets patched very quickly.
None of the hacks in the answers on this question work any longer, and if someone would come up with another dirty hack, eventually it will stop working as well.
I suggest you don't waste energy fighting this and embrace the method that the browser so helpfully gives you — ask the user before you seemingly crash their page.
In other words, unless your webpage's script has control of the window which was opened, you should/cannot close said window. That is because the script running the window.close is not in control of the opened window.
EDIT #3
So many edits I know! But I am answering this in between my daily routine so bear with me. To answer the porthole.js question, it should be much more possible to do something with it, however you need to realize that you are working with iframes.
There is a significant difference when working with websites vs working with iframes, in which iframes are Widgets and websites (including mini sites) are given a URL. There are lots of considerations as well in terms of security and sandboxing, as can be seen on the portholejs demo here. This difference is also what does not allow you to work with different websites the way you want to initially.
My advise would be to evaluate your options with respect to your implementation: website to website vs website to widget.
Good luck!
Ok, I was able to accomplish this in the way I theorized by using porthole.js.
I believe this is the only cross-browser way to accomplish this without using hacks.
The solution consists of 2 apps (you must add code to both app for this to work).
app #1: http://localhost:4000
app #2: http://localhost:5000
In my case, I needed app#1 to spawn a need tab containing app#2. Then I needed app#2 to be able to CLOSE ITSELF upon clicking a button inside app#2.
If these apps were on the same domain (including same port), this would be relatively easy by saving a reference to the tab in app#1:
window.tab = window.open('...', '_blank');
And then accessing that reference from within app#2 via window.opener.tab.close()
However, for my case the apps needed to be on diff domains and doing this method resulted in a browser security exception. So instead, what I needed to do was host app#2 within an iframe inside app#1 (on some specific route, say /iframe), this way they ARE on the same domain as far as the browser windows are concerned, and now the second tab should be able to close itself using window.opener.tab.close().
However, a problem still remained because I needed the trigger to be a button INSIDE app#2 (aka a button inside the iframe), and since the hosting app and the iframe app are again not on the same domain, it seems like I would be back to square one... or maybe not.
In this case, porthole.js saves the day. You must load porthole.js into both apps (this is why you need access to both codebases). Here's the code:
in app#1 (http://localhost:4000/iframe)
// create a proxy window to send to and receive messages from the iFrame
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:5000', 'embedded-iframe');
windowProxy.addEventListener(function(event) {
//handle click event from iframe and close the tab
if(event == 'event:close-window') {
window.opener && window.opener.tab && window.opener.tab.close();
}
});
}
in app#2: (http://localhost:5000)
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:4000/#/iframe');
$('button').on('click', function() {
windowProxy.post('event:close-window');
});
}
And wa-lah, a self closing tab.

How to open a url in an already existing browser tab?

I'd like to do the following in my application via javascript.
1) Press a button from a web page that opens a popup.
2) Select some options in the popup and accept them.
3) Change the content of what is in the first web page according to what has been selected in the popup and change it. A GET Request is acceptable, and if possible popup with the selected options should again be on top, either by putting it on top or by opening a new one with the same options chosen.
I think javascript must have some way of saving the name of the browser tabs your are opening and later, if you want, open a new URL, or put one over other but I cannot find them. The window.open options doesn't look like they can do this.
Any idea on how to achieve this thing? Thanks for your time.
You can try the window.opener method in the popup to access the main page. High level details here: http://www.w3schools.com/jsref/prop_win_opener.asp, but if you Google it there's examples.
We did this for a project and it works, with a few caveats:
Cross domain basically doesn't work, if you have multiple domains you have to get more creative.
Be careful cross browser as well, we had to add some custom javascript to handle
Basically, what you need to do on your main page is define a global javascript method that does what you want it to (it can take parameters). Then, on your popup, you can call it with window.opener.MethodNameHere();
Theoretically, if you do need to handle cross browser, you can try using postmessage, which I believe is only supported in html5 natively (there are plugins for html4), but it would probably be tricky getting it right in this circumstance and I'm not sure how to do it off the top of my head.

Javascript: Check if this window is already opened

I am trying to detect whether the current page is already opened in a different tab or not.
I tried using window.open(), but I get as return the current window itself, not the supposedly other window of same address. It will always return true.
So say, if 'mysite.com' is already opened, when the user opens a new window with 'mysite.com', I shall detect that, focus the other window and close the current one.
Would love to hear any ideas, or whether this is possible. I'm trying to capture all links into a single tab.
You can use localStorage events to communicate between different tabs and therefore detect if a page is already opened. Check this answer: https://stackoverflow.com/a/14792159/60745
Even when you're only concerned with a tab in the same browser on the same machine, the problem with trying to accomplish this through pure javascript is that although you could set a cookie on each of your sites pages (window.onload) to record the user has initially visited your site, there's no safe way to ensure you remove this cookie when they leave.
Although you have the onunload & onbeforeunload events, these are not fired when you leave a site over a link, uses a browsers back button or closes the browser.

Get previous page URL, Open New Window, then Redirect through Javascript

I'm stuck using a CMS that only gives me the ability to modify the content of the <body>, so when I want to redirect people, I've used this
<script type="text/javascript">
window.location = "http://www.example.com/"
</script>
So, yes, the page loads first, and then 5ms later, the redirect happens, and it's worked for all intensive purposes. Now, I'm wondering if I can use javascript to do something else.
Is it possible to open a new browser tab, with a specified URL, and then redirect the user back to the previous page, through Javascript?
Many thanks, SO.
EDIT - Whether it opens a new window or tab, to be honest, is not as important as it actually functioning. I need Javascript to determine the prior page (if possible), then open a new window/tab to a URL I specify, and then redirect the current window/tab to it's prior page. Some are saying that window.open only works on a click event, which will not work for what I am trying accomplish either... just fyi.
So, literally, without clicks, I need Javascript to do the following -
Determine the prior/previous/last page the user came from, store it as a variable
Open a new window or tab, to a specified URL
window.location back to the prior page, which I stored as a variable
Hope that makes sense.
Depending on the user's browser setting using window.open can open the new window in a new tab instead but you CANNOT directly control this through the browser. It is all down to the user's settings.
To open a new window:
window.open("http://www.google.com", "windowName", "window options (optional parameter)");
Then simply use:
history.back();
You can also use the referer property:
var previousUrl = document.referrer;
For more info on window.open, see: http://www.javascript-coder.com/window-popup/javascript-window-open.phtml
For more info on the document.referrer property, take a look at: http://www.netmechanic.com/news/vol4/javascript_no14.htm

Redirect after clicking an external link and only open one tab/window

I have created a jsp for external clients of my application to use to link to the web client. They can specify which client they are in the URL so that when the link opens a window it is named and any other links from that client will open in the same window. Here's an example URL:
mysite.com/redirect.jsp?fromClient=mine&page=awesome
The problem is that when you click on this link, for example from an email digest, it opens the redirect.jsp page which uses window.open() to open the desired page. From the above link, the page that would open would be:
mysite.com/index.jsp?page=awesome
So then I have two pages open, when really I only want one. And since I'm not using javascript to open the first page (it's a link), I can't use window.close() to close it. I've tried working around using window.open('','_parent','') and window.open('','_self','') but neither works.
I know there has to be a better way to redirect than to open a second window from my jsp page, but I don't know what that better way is. Thoughts?
EDIT
Primary goal is for users of external clients to be able to click links in that client and have all the links take them to the same window/tab in a browser. I'm using window.open right now because I can parse the link and get the client name and then supply that in the window.open function.
EDIT 2
I always end up being too vague in these questions. Ok, here's the setup:
An email digest contains a link that looks like
mysite.com/redirect.jsp?fromClient=emailDigest&pageNum=4
Currently, when that link is clicked on, it opens a browser (duh) and then the redirect.jsp page parses that link to get the client name, in this case emailDigest. It then calls window.open('mysite.com/index.jsp?pageNum=4','emailDigest'). This creates a new window with the name emailDigest unless a window/tab with that name already exists, in which case it merely updates the URL in that window with the new one.
I want to either be able to close the original window (the one with the redirect.jsp address) or not have to open that initial window at all.
NOTE
As there are many different clients that want to be able to do this, I cannot guarantee that they will be creating the link with HTML so the target attribute is not the answer.
The correct answer is "No, it cannot be done". If you do not open a window with Javascript then you cannot close it with Javascript. I would always have to create at least 2 windows, which is not what we wanted.
I think you're looking for window.location instead of window.open.
Please use window.location.replace("http://mysite.com/index.jsp?page=awesome");
Reason :
replace(url):Replace the current document with the one at the provided
URL. The difference from the assign() method is that after using
replace() the current page will not be saved in session history,
meaning the user won't be able to use the Back button to navigate to
it.
As haynar says above, why do you open a window and not either:
<!-- content contains the refresh delay in seconds and the target url -->
<meta http-equiv="Refresh" content="1; URL="http://mysite.com/index.jsp?page=awesome">
or use javascript to do the same:
window.location.href = "http://mysite.com/index.jsp?page=awesome";
either works fine and will leave you with one window open.
To get the named window use a targeted link:
Mysite.com
This will automatically set the name property of the opened window.

Categories

Resources