2012-04-01 2 views
5

Nel rispondere my question Pumbaa80 found una differenza tra chiamare open() e window.open(), provare i seguenti esempi in Firefox (testati su 11.0):Qual è la differenza tra open() e window.open() in Firefox?

  1. http://jsfiddle.net/9kqp5/ (chiamate open; apre in una nuova scheda in FF, a condizione che l'impostazione "Apri nuove finestre in una nuova scheda" è attiva, che è predefinita)

  2. http://jsfiddle.net/HLbLu/ (chiamate window.open; apre in una nuova finestra piccola)

Ma perché sulla terra c'è una differenza? Se provo il following example:

<script> 
var a = 2; 
function hello() { alert(this.a); } 

hello(); 
window.hello(); 
</script> 

Entrambe le varianti di chiamando la funzione hello lavoro esattamente lo stesso, compreso avere la stessa this !!!

+1

funziona lo stesso per me, tutto il campione apre la stessa cosa. E in effetti sono la stessa cosa, a meno che tu non definisca un'altra chiamata di chiamata aperta –

+0

Entrambi i JS Fiddles mostrano lo stesso comportamento (aprendo una nuova finestra) anche per me. –

+0

Anche qui, ho provato Opera e Firefox. – Imp

risposta

7

Uno dei suoi violini sta chiamando window.open mentre l'altro sta chiamando document.open, perché la catena portata a gestori di eventi attributo linea è strano. Così finisci allo http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open

Detto questo, dato che passi 3 argomenti, questo dovrebbe essere invocato window.open. La differenza di comportamento sembra essere un bug in Firefox. Ho archiviato https://bugzilla.mozilla.org/show_bug.cgi?id=741266 su quello.

+0

interessante, grazie ... – TMS

+0

No Boris, non avresti dovuto postare quella segnalazione! Ho bisogno di questa funzionalità !!! [Devo essere in grado di aprire una legenda in piccole nuove finestre] (http://stackoverflow.com/q/9956827/684229)! – TMS

+0

Il punto del bug report è che al momento 'document.open' e' window.open' hanno un comportamento diverso nel tuo caso: il primo apre una nuova scheda e quest'ultimo apre una piccola nuova finestra. Dovrebbero avere lo stesso comportamento e tale comportamento dovrebbe essere quello di aprire una piccola nuova finestra. Qual è la patch che ho scritto? dovresti dare un'occhiata alla patch e in particolare al test al suo interno. –

0

Lo sono di fatto lo stesso. Prova window.open === open o window["open"] === open. Se questo ti rende falso, devi essere in una chiusura e il codice di somecode è stato definito aperto.

E ovviamente questo indica tutti gli oggetti che sono membri dell'oggetto globale (finestra).

4

I tuoi due violini funzionano allo stesso modo per me su Chrome.

Tuttavia, le due linee di codice

window.open(...);

e

open(...);

non sono equivalenti. L'unica volta che saranno equivalenti è se il tuo ambito di esecuzione corrente non fornisce una nuova definizione per open, facendo in modo che l'interprete cerchi gli ambiti superiori fino a raggiungere l'ambito globale e trova window.open.

È possibile vedere in azione in this fiddle:

var test = function() { 
    var open = function() { 
     alert('uh oh'); 
    }; 

    window.open('www.google.com'); 
    open('www.google.com'); 
}; 

test(); 
+0

Sì, questo è ovvio, ma se guardi i due violini nella mia domanda, entrambi chiamano 'open' nel contesto globale e comunque c'è una differenza! – TMS

+0

@Tomas Penso che sia necessario specificare la versione di Firefox che si sta utilizzando. Finora nessuno ha riprodotto il fenomeno. –

+0

@AndrewLeach, il più nuovo naturalmente ... (questo è il default :-)). Versione 11.0. – TMS

1

In un browser, il contesto predefinito è window. Ecco perché è possibile chiamare open(), alert() e anche escape() per esempio. Chiamare window.open() equivale esattamente a open().

Come una nuova finestra si apre con la chiamata di funzione open() dipende interamente dal browser.

+0

Ma come si spiega la differenza dei due violini? – TMS

+0

Non c'è differenza. Con le nuove finestre impostate per essere aperte come schede nel browser, si aprono come schede. Con questo unset, si aprono come finestre. Dovresti specificare in quale browser e versione vedi la differenza e quali sono i tuoi nuovi criteri di finestra. Assicurati di non avere alcun plugin speciale in esecuzione che potrebbe influire sulle nuove finestre/navigazione a schede. –

+0

Pumba [ha osservato la stessa differenza qui] (http://stackoverflow.com/a/9962756/684229) ... Non ho alcun plugin con schede speciali, con solo FF 11.0 con Firebug, barra degli strumenti di sviluppo Web e browser RealPlayer registrare i componenti aggiuntivi. Vedi la nota sulle impostazioni che ho aggiornato nella mia domanda. – TMS

1

Questo è davvero molto strano.Sembra che il gestore onclickse aggiunto come attributo ha un contesto con una avvolto open funzione che si differenzia dalla window.open:

http://jsfiddle.net/aFujb/

Questo accade in ultima Firefox, Safari e Chrome. Non riesco a trovare alcuna spiegazione o segnalazione di bug per nessuno dei due browser.

Ho cercato di scoprire cosa sta succedendo nel codice sorgente di Firefox, ma onestamente è troppo per me. Sembra che ci sia two different window.open implementations chiamato nsGlobalWindow::Open e nsGlobalWindow::OpenJS, ma non sono sicuro che questo abbia qualcosa a che fare con la domanda.

+0

Finalmente qualcuno! Grazie per la tua indagine, Pumbaa. – TMS

+1

Non è un bug. Nel tuo violino, la ricerca bareword di 'open' sta avvenendo in un' onclick'attributo_, quindi viene cercata sull'elemento su cui si trova l'attributo, quindi sul documento, quindi sulla finestra. E così ovviamente trova 'document.open' prima che arrivi alla finestra ... –

+0

@BorisZbarsky ha ragione; vedere [la mia risposta] (http://stackoverflow.com/a/9970045/249624) per una spiegazione del perché. –

5

All'interno del gestore eventi, open risolverà da solo a document.open. Come menzionato da Boris Zbarsky in un commento e in his answer, questo comportamento è previsto, specificato da HTML5. In the section on event handlers, passaggio 6 specifica:

6. Utilizzando l'ambiente di esecuzione script creato sopra, crea un oggetto funzione (come definito nella edizione ECMAScript 5 sezione 13.2 Creazione di oggetti funzionali), con:

(...)
lessicale Ambiente Ambito

  1. Let Ambito essere il risultato di NewObjectEnvironment (documento dell'elemento, il g ambiente lobal).
  2. Se l'elemento ha un proprietario del modulo, lasciare che Scope sia il risultato di NewObjectEnvironment (il proprietario del modulo dell'elemento, Scope).
  3. Lascia che Scope sia il risultato di NewObjectEnvironment (l'oggetto dell'elemento, Scope).
    (...)

In altre parole, i riferimenti delle variabili all'interno del gestore di eventi sarà risolto nell'ordine:

  1. ambito locale
  2. proprietà degli elementi
  3. modulo proprietario proprietà (se applicabile)
  4. document proprietà
  5. portata globale
+0

Aha, buon lavoro! Un comportamento molto strano però. È come se il conduttore fosse avvolto in blocchi 'con' nidificati. Non me lo sarei mai aspettato. – user123444555621

+0

Grazie, ottima spiegazione! – TMS

+0

@ Pumbaa80 Nidificato con blocchi è esattamente come è il comportamento. Sì, è stravagante, ma è sempre stato così per sempre nei browser, e purtroppo molti siti dipendono da questo. –