2015-11-04 15 views
7

Sono appena iniziato con Electron, con esperienza precedente con node-webkit (nw.js).Come posso accedere al DOM di un <webview> in Elettron?

In nw.js, sono stato in grado di creare iframe e quindi accedere al DOM di detti iframe per afferrare elementi come il titolo, favicon, & c. Quando ho preso Electron pochi giorni fa per portarvi la mia app nw.js, ho visto consigli per usare le visioni web invece degli iframe, semplicemente perché erano migliori. Ora, la funzionalità che ho menzionato sopra era relativamente facile da fare in nw.js, ma non so come farlo in Electron (e gli esempi sono magri a nessuno). Qualcuno può aiutare?

Inoltre, ho i pulsanti indietro/avanti per la mia webview (e intendo avere più di uno). Ho visto nella documentazione che potrei chiamare le funzioni per farlo su una webview, ma non ho nemmeno tentato di provarlo (e, non ho trovato esempi di come venissero usate allo stato selvatico).

+0

Per i futuri utenti: la soluzione migliore è utilizzare il modulo ipc. C'è un semplice esempio di come puoi usarlo per comunicare tra la tua pagina principale e la tua webview in electron docs: https://github.com/electron/electron/blob/master/docs/api/web-view-tag .md # event-ipc-message – JoeRocc

risposta

5

Oltre a guest per ospitare chiamate IPC come NetOperatorWibby, è anche molto utile passare da host a guest. L'unico modo per farlo al momento è usare lo <webview>.executeJavaScript(code, userGesture). Questa API è un po 'rozza ma funziona.

Se si sta lavorando con un ospite remoto, ad esempio "estendendo" una pagina Web di terzi, è anche possibile utilizzare l'attributo webview preload che esegue lo script personalizzato prima di eseguire qualsiasi altro script nella pagina. È sufficiente notare che l'API di pre-caricamento, per motivi di sicurezza, eseguirà tutte le funzioni create nello spazio dei nomi radice del file JS personalizzato al termine dello script personalizzato, tuttavia questo processo di custodia non eseguirà il nuke degli oggetti dichiarati nella directory principale. Quindi, se vuoi che le tue funzioni personalizzate persistano, raggruppale in un oggetto singleton e le tue API personalizzate rimarranno dopo il caricamento completo della pagina.

[update] Ecco un semplice esempio che ho appena finito di scrivere: Electron-Webview-Host-to-Guest-RPC-Sample

+0

Hmm, dovrò provarlo. Avete qualche esempio di quella funzione executeJavaScript? –

+0

Sicuro. Riscriverò un esempio di base. –

+0

L'esempio che ho postato è molto semplice ma dovresti ottenere il succo dell'idea. Mi sono appena imbattuto in questa scorsa notte, quindi sto solo iniziando ma prevedo che scriverò un singolo gestore nel guest che accetta un messaggio JSON con codifica Base64 che sarebbe stato decodificato ed elaborato nel gestore guest. –

8

Non so chi abbia votato per chiudere la mia domanda, ma sono contento che non sia andato a buon fine. Altre persone hanno questa domanda anche altrove online. Ho anche spiegato quello che volevo ottenere, ma w/e.


Ho finito per utilizzare ipc-message. Il documentation potrebbe usare più esempi/spiegazioni per il laico, ma hey, l'ho capito. Il mio codice è here e here, ma pubblicherò anche esempi di seguito se il mio codice dovesse scomparire per qualsiasi motivo.


Questo codice è in aries.js, e questo file è incluso nella pagina renderer principale, che è index.html.

var ipc = require("ipc"); 
var webview = document.getElementsByClassName("tabs-pane active")[0]; 

webview.addEventListener("ipc-message", function (e) { 
    if (e.channel === "window-data") { 
    // console.log(e.args[0]); 

    $(".tab.active .tab-favicon").attr("src", e.args[0].favicon); 
    $(".tab.active .tab-title").html(e.args[0].title); 
    $("#url-bar").val(e.args[0].url); 

    $("#aries-titlebar h1").html("Aries | " + e.args[0].title); 
    } 

    // TODO 
    // Make this better...cancel out setTimeout? 
    var timer; 

    if (e.channel === "mouseover-href") { 
    // console.log(e.args[0]); 
    $(".linker").html(e.args[0]).stop().addClass("active"); 

    clearTimeout(timer); 

    timer = setTimeout(function() { 
     $(".linker").stop().removeClass("active"); 
    }, 1500); 
    } 
}); 

Il prossimo pezzo di codice è in browser.js, e questo file viene iniettato nel mio <webview>.

var ipc = require("ipc"); 

document.addEventListener("mouseover", function (e) { 
    var hoveredEl = e.target; 

    if (hoveredEl.tagName !== "A") { 
    return; 
    } 

    ipc.sendToHost("mouseover-href", hoveredEl.href); 
}); 

document.addEventListener("DOMContentLoaded", function() { 
    var data = { 
    "title": document.title, 
    "url": window.location.href, 
    // need to make my own version, can't rely on Google forever 
    // maybe have this URL fetcher hosted on hikar.io? 
    "favicon": "https://www.google.com/s2/favicons?domain=" + window.location.href 
    }; 

    ipc.sendToHost("window-data", data); 
}); 

non ho trovato un modo affidabile per iniettare jQuery in <webview> s, e probabilmente non dovrei perché la pagina sarei iniettando potrebbe già averlo (nel caso in cui vi state chiedendo perché il mio codice principale è jQuery, ma c'è anche un normale JavaScript).

+0

Cosa intendi con "questo file viene iniettato nel mio ". Includete il file nel guest - sito Web o l'iniezione fatta da qualche codice elettronico? –

+0

La webview è una div. Come

. Electron mi consente di inserire browser.js nella webview che sta caricando un sito web. –

+0

Lo metti usando l'attributo preload? () –

0

Ciò si riferisce alla risposta precedente (non mi è permesso di commentare): Informazioni importanti per quanto riguarda ipc modulo per gli utenti di Electron 1.x:

il modulo IPC è stata suddivisa in due moduli separati:

  • ipcMain per il processo principale
  • ipcRenderer per il processo di rendering

Quindi, hanno bisogno di esempi precedenti da correggere, invece di

// Outdated - doesn't work in 1.x  
var ipc = require("ipc"); 

uso:

// In main process. 
var ipcMain = require('electron').ipcMain 

E:

// In renderer process. 
var ipcRenderer = require('electron').ipcRenderer 

S ee: sezione http://electron.atom.io/blog/2015/11/17/electron-api-changes su 'Splitting the ipc module'