How can I open a new tab using javascript without switching to the new tab?
For example, when a user clicks on a link a new tab is to be opened, but the user should stay on the current tab.
The web browser automatically focuses on the new tab, but you can call the focus back:
function openWindow( url )
{
window.open(url, '_blank');
window.focus();
}
Click Me
Unfortunately, you can't currently do that -- but you can get close. You can open a new window, and if you do that without specifying any window dimensions or window features, most modern browsers will open a new tab instead (depending on the user's preferences, but then, you want to do what the user prefers anyway, right?). So just window.open(url) or window.open(url, name) if you're going to use the name for something. Be sure to do this in direct response to a user-initiated event, otherwise the browser's pop-up blocker will probably...block the pop-up. :-)
Live example
Regarding keeping focus on your window...good luck with that. You can call window.focus() after window.open(...), but in my experience it doesn't usually work.
Throwing it out there: If you make the thing the user interacts with a genuine link with a URL, the user can decide whether to open it in a new tab, a new window, whatever and whether to give it focus (if they're sophisticated enough to know Shift+Click and Ctrl+Shift+Click, or the right-click menu).
Unfortunately, you can't do this in ALL browsers, but you can do this in Chrome if you implement browser's extension.
How to manipulate with tabs in Chrome by javascript:
http://code.google.com/chrome/extensions/tabs.html
chrome.tabs.create(object createProperties, function callback)
Creates a new tab. Note: This function can be used without requesting the 'tabs' permission in the manifest.
Parameters
**createProperties** ( object )
**windowId** ( optional integer )
The window to create the new tab in. Defaults to the current window.
**index** ( optional integer )
The position the tab should take in the window. The provided value will be clamped to between zero and the number of tabs in the window.
**url** ( optional string )
The URL to navigate the tab to initially. Fully-qualified URLs must include a scheme (i.e. 'http://www.google.com', not 'www.google.com'). Relative URLs will be relative to the current page within the extension. Defaults to the New Tab Page.
**selected** ( optional boolean )
Whether the tab should become the selected tab in the window. Defaults to true
pinned ( optional boolean )
Whether the tab should be pinned. Defaults to false
**callback** ( optional function )
This is user specific settings, you cannot change this behavior from JS.
(function(a) {
document.body.appendChild(a);
a.setAttribute('href', location.href);
a.dispatchEvent((function(e) {
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0,
true, false, false, false, 0, null);
return e
}(document.createEvent('MouseEvents'))))
}(document.createElement('a')))
For me, using
window.open("https://stackoverflow.com");
worked perfectly. What this does depends on what browser you are using, what operating system, and your personal preferences.
Chrome, Internet Explorer, and Firefox all opened a new tab. Sorry if this doesn't work for you.
(Just realized that this is an old thread)
var isMobile = false;
if (
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(
navigator.userAgent
) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
navigator.userAgent.substr(0, 4)
)
) {
isMobile = true;
}
if (isMobile) {
window.location.assign(url);
} else {
window.open(url);
}
in mac: Cmd+click and in windows: ctrl+click will open new tabs in the background. Perhaps this is an issue of user training rather than something that needs to be solved programmatically?
source:
https://support.google.com/chrome/answer/157179?co=GENIE.Platform%3DDesktop&hl=en#zippy=%2Ctab-and-window-shortcuts%2Cmouse-shortcuts
Post is old but without any 100% correct answer.
SOLUTION FOR ALL BROWSERs:
you can open new tab to same domain URLs via :
window.open("newurl.php", "_blank");
and for cross-domain new tabs, you must create a simple local script, like this :
in new file "redirect.php" you pass a parameter (target new tab url ) like this
<?php
$newURL=$_GET['u'];
header('Location: '.$newURL);
؟>
and you can create a new tab with any target url with :
window.open("redirect.php?u=http://www.google.com", "_blank");
:)
its my solution in my website. and work with any
Related
Summary: I need to find a way to accomplish with programmatic injection the same exact behaviour as using content_scripts > matches with "all_frames": true on a manifest. Why? because it is the only way I've found of injecting iframe's content in an extension page without having Cross-Origin errors.
I'm moving to optional_permissions on a Chrome extension and I'm on a dead end.
What I want:
Move this behaviour to optional_permissions in order to be able to add more hosts in the future. With the current code, by adding one new host on content_scripts > matches the extension is disabled by Chrome.
For the move, I removed content_scripts in the manifest and I added "optional_permissions": ["*://*/"],. Then, I successfully implemented a dialog asking new permissions to the user with chrome.permissions.request.
As I said before, the problem is how to inject the iframe's content in an extension page.
What I've tried:
chrome.declarativeContent.RequestContentScript (mentioned here) with allFrames: true. I can only see the script running if I enter the URL directly, nothing happens when that URL is set in an iframe.
chrome.tabs.onUpdated: url is undefined for an extension page. Also, the iframe url is not detected.
Call chrome.tabs.executeScript with allFrames: true as soon as I load the first iframe. By doing this I get an exception Cannot access contents of the page. Extension manifest must request permission to access the respective host. and the "respective host" is chrome-extension://, which is not a valid host if you want to add it to the permissions.
I'm lost. I couldn't find a way to simulate the same behaviour as content_scripts > matches with programmatic injection.
Note: using webNavigation API is not an option since the extension is live and it has thousands of users. Because of this, I can not use the frameId property for executeScript. Thus, my only option with executeScript was to inject all frames but the chrome-extension host issue do not let me continue.
Update: I was able to accomplish what I wanted but only on an HTTP host. I used chrome.tabs.executeScript (option 3).
The question remains on how to make this work on an extension page.
You cannot run content scripts in any extension page, including your own.
If you want to run code in a subframe of your extension page, then you have to use frameId. There are two ways to do this, with and without webNavigation.
I've put all code snippets in this answer together (with some buttons to invoke the individual code snippets) and shared it at https://robwu.nl/s/optional_permissions-script-subframe.zip
To try it out, download and extract the zip file, load the extension at chrome://extensions and click on the extension button to open the test page.
Request optional permissions
Since the goal is to programmatically run scripts with optional permissions, you need to request the permission. My example will use example.com.
If you want to use the webNavigation API too, include its permission in the permission request too.
chrome.permissions.request({
// permissions: ['webNavigation'], // uncomment if you want this.
origins: ['*://*.example.com/*'],
}, function(granted) {
alert('Permission was ' + (granted ? '' : 'not ') + 'granted!');
});
Inject script in subframe
Once you have a tab ID and frameId, injecting scripts in a specific frame is easy. Because of the tabId requirement, this method can only work for frames in tabs, not for frames in your browserAction/pageAction popup or background page!
To demonstrate that code execution succeeds, my examples below will call the next injectInFrame function once the tabId and frameId is known.
function injectInFrame(tabId, frameId) {
chrome.tabs.executeScript(tabId, {
frameId,
code: 'document.body.textContent = "The document content replaced with content at " + new Date().toLocaleString();',
});
}
If you want to run code not just in the specific frame, but all sub frames of that frame, just add allFrames: true to the chrome.tabs.executeScript call.
Option 1: Use webNavigation to find frameId
Use chrome.tabs.getCurrent to find the ID of the tab where the script runs (or chrome.tabs.query with {active:true,currentWindow:true} if you want to know the current tabId from another script (e.g. background script).
After that, use chrome.webNavigation.getAllFrames to query all frames in the tab. The primary way of identifying a frame is by the URL of the page, so you have a problem if the framed page redirects elsewhere, or if there are multiple frames with the same URL. Here is an example:
// Assuming that you already have a frame in your document,
// i.e. <iframe src="https://example.com"></iframe>
chrome.tabs.getCurrent(function(tab) {
chrome.webNavigation.getAllFrames({
tabId: tab.id,
}, function(frames) {
for (var frame of frames) {
if (frame.url === 'https://example.com/') {
injectInFrame(tab.id, frame.frameId);
break;
}
}
});
});
Option 2: Use helper page in the frame to find frameId
The option with webNavigation looks simple but has two main disadvantages:
It requires the webNavigation permission (causing the "Read your browsing history" permission warning)
The identification of the frame can fail if there are multiple frames with the same URL.
An alternative is to first open an extension page that sends an extension message, and find the frameId (and tab ID) in the metadata that is made available in the second parameter of the chrome.runtime.onMessage listener. This code is more complicated than the other option, but it is more reliable and does not require any additional permissions.
framehelper.html
<script src="framehelper.js"></script>
framehelper.js
var parentOrigin = location.ancestorOrigins[location.ancestorOrigins.length - 1];
if (parentOrigin === location.origin) {
// Only send a message if the frame was opened by ourselves.
chrome.runtime.sendMessage(location.hash.slice(1));
}
Code to be run in your extension page:
chrome.runtime.onMessage.addListener(frameMessageListener);
var randomMessage = 'Random message: ' + Math.random();
var f = document.createElement('iframe');
f.src = chrome.runtime.getURL('framehelper.html') + '#' + randomMessage;
document.body.appendChild(f);
function frameMessageListener(msg, sender) {
if (msg !== randomMessage) return;
var tabId = sender.tab.id;
var frameId = sender.frameId;
chrome.runtime.onMessage.removeListener(frameMessageListener);
// Note: This will cause the script to be run on the first load.
// If the frame redirects elsewhere, then the injection can seemingly fail.
f.addEventListener('load', function onload() {
f.removeEventListener('load', onload);
injectInFrame(tabId, frameId);
});
f.src = 'https://example.com';
}
I want know if is it possible to make Google Chrome behave like a kiosk (without a frame or controls) but not in full screen, like the next mock picture:
My solution in Electron:
var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is GCed.
var mainWindow = null;
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600, frame:false});
// and load the index.html of the app.
mainWindow.loadURL('http://www.google.com/');
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
});
I do not think that it's possible to make Chrome itself behave that way, but a Chrome App (not an extension) can do this.
This is an option in window creation:
chrome.app.window.create("app.html", {
frame: "none"
});
Note that you will have to provide your own controls to close/move the window.
To make it behave like a browser, you'll need to embed a <webview> element. See also a browser app example.
However, note that Chrome Apps are being deprecated.
You should consider using a similar platform, like Electron or NW.js, to build your own "mini-browser" for your purpose.
Passing options to a regular PageControl via options is fine, but how do you pass options to a Settings page?
i.e. Settings pages using a SettingsFlyout still have the "ready: function (element, options)" event, but how do you set the options? The navigation is set in the application activated event, but there doesn't seem to be the opportunity to set options...
WinJS.Application.onsettings = function ( e )
{
e.detail.applicationcommands =
{
"about": { href: "/settings/about/about.html", title: "About" },
};
WinJS.UI.SettingsFlyout.populateSettings( e );
}
Like #devhammer said, you're not navigating to the settings page. In fact, it's a SettingsFlyout that is just showing up over your current page. There's not really any need to pass anything though because the SettingsFlyout will have access to the state of your page. You can define a variable in your main page and then access it on the settings page.
If you have application level data, you can just tack some state onto the app object. What I do is move the var app = WinJS.Application line that is in the default.js by default into global scope so I can access it from anywhere, and then I use that from where I need.
By the way, don't listen to the people that tell you that global scope is evil. As long as you're aware of what you're putting in global scope and why, it's just fine to use.
Given that you're not navigating to the page using the normal WinJS.Navigation.navigate method, I'm not sure you can pass any state beyond the title and URI for the settings pages you wish to add.
As such, the options argument on the settings page will always be undefined.
I've made an extension who's purpose is to redirect urls.
I.e: www.google.com becomes: www.mysite.com/?url=www.google.com
I came across this post:
How to modify current url location in chrome via extensions
The problem I'm having is that the url's are both processed. The tab initially loads up google.com and only after it's finished my request is shown ( www.mysite.com/?url=www.google.com).
Is there any way to stop the initial request from being processed?
Something like:
chrome.tabs.onUpdated.addListener(function(tabId,obj,tab){
update.stop() // ??????????? Here I'm missing...
chrome.tabs.update(tabId,{url:....}, function callback); // My update stuff..
});
Thoughts?
thank you all.
You're looking for the webNavigation API.
You can register listeners to handle user navigation by modifying or blocking the request on the fly.
In the example below, when a user navigate to www.google.com, before the page even start loading onBeforeNavigate is fired and you can redirect the user to the CSS validation page for that URL:
chrome.webNavigation.onBeforeNavigate.addListener((details) => {
if(details.url.indexOf("www.google.com") !== -1)) {
chrome.tabs.update(details.tabId, {
url: "https://jigsaw.w3.org/css-validator/validator?uri=" + details.url
});
}
});
Remember to add the "webNavigation" permission to your extension manifest to get this functionality enabled.
chrome.tabs.onUpdated is fired two times per tab load - once a tab starts loading, and another time when it finishes loading. If you attach your update to the tab start loading event then it should work relatively quickly. You will still see original url being loaded for a brief moment, but it won't wait until it finishes, as you are describing.
chrome.tabs.onUpdated.addListener(function(tabId,obj,tab){
if(obj.status == "loading") {
chrome.tabs.update(tabId,{url:....}, function callback);
}
});
I don't think there is a more efficient solution at the moment.
I know how to open a small window:
function SmallWindow(theURL,winName)
{window.open(theURL,winName,'toolbar=yes,scrollbars=yes,
menubar=yes,toolbar=yes,resizable=yes,width=800,height=500,left=300,top=200');}
being called as
<a href="http://newURL.html" onclick="SmallWindow(this.href, ''); return false">
Click here</a>
The problem is that with many clicks in various links of a big window this produces a sequence of different small windows. I want all those small windows overlapping each other on the same window. I tried to give a window name, WIN
function SmallWindow(theURL,winName)
{window.open(theURL,"WIN",'toolbar=yes,scrollbars=yes,menubar=yes,toolbar=yes,
resizable=yes,width=800,height=500,left=300,top=200');
but when a new small window is opened, the browser does not jump to it, and the user does not get aware that the new small window was opened!
I could not find an answer to this problem. Thanks for any help.
The call to window.open will return a reference to the new window (or existing window in the case where a window with the same name is already open). You can then call the focus() method on that window to bring it to the front.
function SmallWindow(theURL, winName)
{
var myWindow = window.open(theURL, winName,'toolbar=yes,scrollbars=yes,menubar=yes,toolbar=yes, resizable=yes,width=800,height=500,left=300,top=200');
myWindow.focus();
}
I think you can bring the popup window to the from like this:
var newWin = window.open(url, "WIN", ...);
newWin.focus();
As you already found out, it is important to always use the same window name (e.g. "WIN"). Otherwise a new window will be opened with every window.open() call.
The focus() method will then bring the window to the front.