2014-07-11 17 views
12

LIVE DEMOAngularJS: come aprire un file in una nuova scheda?

dato un URI di un file, mi piacerebbe aprirlo in una nuova scheda (non una nuova finestra).

It looks likenon è possibile utilizzare $window.open(uri, '_blank').

Così, ho provato il seguente trucco:

var link = angular.element('<a href="uri-here" target="_blank"></a>'); 
angular.element(document.body).append(link); 
link[0].click(); 
link.remove(); 

e it works.

Ma, se inserisco esattamente lo stesso codice in un callback di promessa, non funziona più (apre il file in una nuova finestra).

Qualche idea di cosa sta succedendo qui?

PLAYGROUND HERE

+4

Non è possibile. È una preferenza degli utenti se le nuove pagine si aprono in una finestra o in una nuova scheda e non possono essere modificate. –

+0

Il tuo parco giochi demo sembra funzionare come previsto. Sono su IE 11. – pixelbits

+0

@pixelbits Interessante. Sembra funzionare anche in Firefox 30.0. Mi chiedo il motivo per cui non funziona in Chrome (35.0 nel mio caso). –

risposta

0

working version

$http.get('https://api.github.com/users/angular').then(openInNewTab()); 

EDIT ----------------

Non so perché, ma il metodo di click() chiamato da una funzione di callback agisce diversamente dal chiamarlo direttamente.

È possibile visualizzarlo qui con un esempio di intervallo impostato.

Ecco perché ho chiamato direttamente la funzione piuttosto che passare attraverso un callback.

see it with timer callback

+0

Suggerisco di usare .success(), quindi puoi modificare i risultati se ottieni una condizione di errore. Tuttavia, questa non è la domanda. Il problema è che vogliono sovrascrivere una funzione del browser: "in una nuova scheda (non una nuova finestra)" – Brian

+0

Qualche idea sul perché '.then (openInNewTab())' funziona ma '.then (openInNewTab)' no? –

+0

. Quindi si aspetta una funzione. Quando viene chiamato openInNewTab(), è il valore restituito che viene passato a "then". Ma openInNewTab non restituisce nulla, non è definito. Sospetto che possa funzionare per le ragioni sbagliate. – pixelbits

11

dal codice/contenuti, è non può forzare il browser per aprire una nuova scheda (piuttosto che una nuova finestra, o viceversa). Spetta alle impostazioni del browser forzarlo in un modo o nell'altro.

Qualsiasi altra cosa sarebbe un rischio per la sicurezza.

+0

Potresti spiegare perché questo sarebbe un rischio per la sicurezza? Perché pensi che l'apertura in una nuova scheda sia il comportamento predefinito in Firefox e IE, ma non in Chrome? –

+0

Si tratta di essere in grado di attirare (o eludere) l'attenzione dell'utente finale. I browser hanno strategie predefinite per come aprono nuove finestre (cosa fa effettivamente la funzionalità) e se invece/opzionalmente le aprono all'interno della stessa finestra sotto una nuova scheda. Gli utenti si abituano a qualsiasi strategia del browser. I browser consentono agli utenti finali (non ai siti Web) di ignorare la strategia predefinita. Potendo costringerlo in un modo o nell'altro, otterresti la possibilità di avere il tuo nuovo contenuto * inosservato * da alcuni utenti e/o infastidire altri utenti che hanno già espresso la loro preferenza. –

0

oppure è possibile utilizzare il servizio $ finestra vedere qui: http://plnkr.co/edit/8egebfFj4T3LwM0Kd64s?p=preview

angular.module("Demo", []).controller("DemoCtrl", function($scope, $http, $window) { 
    $scope.uri = 'http://martinfowler.com/ieeeSoftware/whenType.pdf'; 

    function openInNewTab() { 

    var link = angular.element('<a href="' + $scope.uri + '" target="_blank"></a>'); 

    angular.element(document.body).append(link); 

    link[0].click(); 
    link.remove(); 
    } 

    $scope.works = openInNewTab; 

    $scope.doesntWork = function() { 
    $http.get('https://api.github.com/users/angular').then($window.open($scope.uri)); 
    }; 
}); 
+1

questo '$ window.open ($ scope.uri)' viene eseguito 'immediatamente' e il valore restituito viene passato a' .then'. Ecco perché funziona. –

2

È possibile aprire solo nuove finestre all'interno click gestori di eventi sparati da parte dell'utente.

Il motivo è utilizzabile.

Non sono sicuro che tutti i browser abbiano questo comportamento ma alcuni browser non consentono agli script di aprire Windows senza che l'utente venga notato. Immagina quando visiti una pagina web e improvvisamente, la pagina web apre diverse finestre => è fastidioso.

Vedere questo DEMO (testato con il mio Chrome e Firefox), anche noi attiviamo l'evento click per script, il browser blocca ancora il popup.

$("#test").click(function(){ 
    openInNewTab(); 
}); 

$("#test").click(); 

Non è possibile aprire una nuova finestra all'interno il callback successo ajax perché il vostro successo Ajax viene eseguito in un altro ciclo dopo il gestore di eventi click ha terminato sua esecuzione.

Vai a questa link per una soluzione

se metto esattamente lo stesso codice in una richiamata promessa, non funziona più (si apre il file in una nuova finestra, invece).

Sono sorpreso che tu sia ancora in grado di aprire una nuova finestra. Ma questo problema ha davvero un sacco di cose da fare con gli eventi di scatto licenziati dall'utente.

+0

BTW, il tuo link http://jsbin.com/cuhekeve/1/edit è bloccato nei miei browser (Chrome e Firefox) perché non è all'interno di un gestore di eventi click licenziato dall'utente. –

4

Cerchiamo di capire come funziona il blocco pop-up.

Se l'utente attivare la funzione di aprire un nuovo URL, poi pop-up blocker lo permetterà (dovrebbe applicare a qualsiasi browser moderno - almeno Firefox, Chrome)

se non da utente (come javascript funzione background, promessa o qualsiasi altra funzione non attivata dall'utente), il browser bloccherà a meno che l'utente non autorizzi manualmente il sito.

Questo non funziona.

function openInNewTab() { 
    window.open('http://stackoverflow.com','_blank'); 
} 

openInNewTab();//fail 

Questo è il lavoro

<h1><button onclick="openInNewTab()">Open In New Tab - working</button></h1> 

ho creato semplice versione plunkr - http://plnkr.co/edit/QqsEzMtG5oawZsQq0XBV?p=preview

Quindi, per rispondere alla tua domanda. È impossibile a meno che l'utente non lo autorizzi (l'utente lo attiva o il bianco indica il sito).

Citazione di Firefox -

finestre pop-up o pop-up, sono finestre che compaiono automaticamente senza il vostro permesso.

https://support.mozilla.org/en-US/kb/pop-blocker-settings-exceptions-troubleshooting

* Aprire in una nuova scheda/le nuove finestre non fa alcuna differenza. Il blocco popup bloccherà sempre. Ciò non significa che il browser consentirà se aperto in una nuova scheda. E 'solo per coincidenza che per alcune impostazioni predefinite del browser le impostazioni in quel modo.

Soluzione

Si può chiedere all'utente in modo esplicito per attivare la funzione di aprire in una nuova scheda dopo l'esecuzione di sfondo.
È possibile visualizzare il messaggio nell'interfaccia utente per chiedere all'utente di aprire l'url. Esempio - http://plnkr.co/edit/iyNzpg64DtsrijAGbHlT?p=preview

1

Il tuo problema è duplice, e entrambe le pieghe calpestano il territorio incerto.


Ai vecchi tempi di browser, window.open ha fatto esattamente questo – aprire una nuova finestra. Questo perché il concetto di schede non era ancora stato inventato. Quando le schede sono state introdotte, sono state trattate esattamente come Windows per migliorare la compatibilità e questa tradizione continua ancora oggi. Ciò, e il fatto che window.open fosse solo standardized very recently, significa che JavaScript non è in grado di distinguere tra finestre e schede.

Non esiste un modo "normale" per specificare se un collegamento deve essere aperto in una nuova scheda o no. È possibile ricorrendo a un trucco, però: specificare un formato finestra personalizzata alla chiamata open (attraverso il terzo argomento), in questo modo:

window.open('http://example.com', '', 'width=' + screen.width); 

Questo farà sì che quasi tutti i browser per aprire una finestra separata, perché le schede non può avere dimensioni personalizzate.


In JavaScript, ci sono fidati eventi e non attendibili eventi. Gli eventi attendibili sono, ad esempio, clic legittimi su un collegamento da parte dell'utente, mentre un evento non attendibile sarebbe una chiamata manuale click() su un collegamento.

Solo gestori di eventi attendibili possono aprire nuove finestre/schede. Questo serve a prevenire attacchi lato client che bloccano il browser o confondono un utente aprendo rapidamente un centinaio di schede su mouseover o qualcosa di simile.

Il secondo esempio non funziona perché il blocco popup blocca l'evento non attendibile che è stato attivato tramite click(). Sebbene sia stato causato da un clic reale, la chiamata asincrona tra i due interrompe il collegamento alla fiducia.

Problemi correlati