Domanda

Ho provato questo:

string newScript = textBox1.Text;
HtmlElement head = browserCtrl.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = browserCtrl.Document.CreateElement("script");
lblStatus.Text = scriptEl.GetType().ToString();
scriptEl.SetAttribute("type", "text/javascript");
head.AppendChild(scriptEl);
scriptEl.InnerHtml = "function sayHello() { alert('hello') }";

scriptEl.InnerHtml e scriptEl.InnerText forniscono entrambi errori:

System.NotSupportedException: Property is not supported on this type of HtmlElement.
   at System.Windows.Forms.HtmlElement.set_InnerHtml(String value)
   at SForceApp.Form1.button1_Click(Object sender, EventArgs e) in d:\jsight\installs\SForceApp\SForceApp\Form1.cs:line 31
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

C'è un modo semplice per iniettare uno script nella dom?

È stato utile?

Soluzione

Per qualche ragione la soluzione di Richard non ha funzionato da parte mia (insertAdjacentText non è riuscito con un'eccezione). Questo tuttavia sembra funzionare:

HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "function sayHello() { alert('hello') }";
head.AppendChild(scriptEl);
webBrowser1.Document.InvokeScript("sayHello");

Questa risposta spiega come inserire IHTMLScriptElement l'interfaccia nel tuo progetto.

Altri suggerimenti

HtmlDocument doc = browser.Document;
HtmlElement head = doc.GetElementsByTagName("head")[0];
HtmlElement s = doc.CreateElement("script");
s.SetAttribute("text","function sayHello() { alert('hello'); }");
head.AppendChild(s);
browser.Document.InvokeScript("sayHello");

(testato in .NET 4 / App Windows Forms)

Modifica: risolto il problema relativo al caso nel set di funzioni.

Ecco il modo più semplice che ho trovato dopo aver lavorato su questo:

string javascript = "alert('Hello');";
// or any combination of your JavaScript commands
// (including function calls, variables... etc)

// WebBrowser webBrowser1 is what you are using for your web browser
webBrowser1.Document.InvokeScript("eval", new object[] { javascript });

Ciò che fa la funzione JavaScript globale eval(str) è analizzare ed eseguire ciò che è scritto in str. Controlla w3schools ref qui .

Inoltre, in .NET 4 questo è ancora più semplice se si utilizza la parola chiave dinamica:

dynamic document = this.browser.Document;
dynamic head = document.GetElementsByTagName("head")[0];
dynamic scriptEl = document.CreateElement("script");
scriptEl.text = ...;
head.AppendChild(scriptEl);

Se tutto ciò che vuoi davvero è eseguire javascript, questo sarebbe più semplice (VB .Net):

MyWebBrowser.Navigate("javascript:function foo(){alert('hello');}foo();")

Suppongo che questo non " iniettare " ma eseguirà la tua funzione, se è quello che stai cercando. (Nel caso in cui tu abbia complicato troppo il problema.) E se riesci a capire come iniettare in javascript, inseriscilo nel corpo della funzione & Quot; foo & Quot; e lascia che javascript faccia l'iniezione per te.

Il wrapper gestito per il documento HTML non implementa completamente le funzionalità necessarie, quindi è necessario immergersi nell'API MSHTML per ottenere ciò che si desidera:

1) Aggiungi un riferimento a MSHTML, che verrà chiamato "!" quot; Libreria di oggetti HTML Microsoft " sotto i riferimenti COM .

2) Aggiungi 'using mshtml;' ai tuoi spazi dei nomi.

3) Ottieni un riferimento al IHTMLElement dell'elemento script:

IHTMLElement iScriptEl = (IHTMLElement)scriptEl.DomElement;

4) Chiama il metodo insertAdjacentText, con il primo valore del parametro di " afterBegin " ;. Tutti i possibili valori sono elencati qui :

iScriptEl.insertAdjacentText("afterBegin", "function sayHello() { alert('hello') }");

5) Ora puoi vedere il codice nella proprietà scriptEl.InnerText.

Hth, Richard

Come seguito alla risposta accettata , questa è una definizione minima di IHTMLScriptElement interfaccia che non richiede l'inclusione di un tipo aggiuntivo biblioteche:

[ComImport, ComVisible(true), Guid(@"3050f28b-98b5-11cf-bb82-00aa00bdce0b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
[TypeLibType(TypeLibTypeFlags.FDispatchable)]
public interface IHTMLScriptElement
{
    [DispId(1006)]
    string text { set; [return: MarshalAs(UnmanagedType.BStr)] get; }
}

Quindi un codice completo all'interno di una classe derivata dal controllo WebBrowser sarebbe simile:

protected override void OnDocumentCompleted(
    WebBrowserDocumentCompletedEventArgs e)
{
    base.OnDocumentCompleted(e);

    // Disable text selection.
    var doc = Document;
    if (doc != null)
    {
        var heads = doc.GetElementsByTagName(@"head");
        if (heads.Count > 0)
        {
            var scriptEl = doc.CreateElement(@"script");
            if (scriptEl != null)
            {
                var element = (IHTMLScriptElement)scriptEl.DomElement;
                element.text =
                    @"function disableSelection()
                    { 
                        document.body.onselectstart=function(){ return false; }; 
                        document.body.ondragstart=function() { return false; };
                    }";
                heads[0].AppendChild(scriptEl);
                doc.InvokeScript(@"disableSelection");
            }
        }
    }
}

questa è una soluzione che utilizza mshtml

IHTMLDocument2 doc = new HTMLDocumentClass();
doc.write(new object[] { File.ReadAllText(filePath) });
doc.close();

IHTMLElement head = (IHTMLElement)((IHTMLElementCollection)doc.all.tags("head")).item(null, 0);
IHTMLScriptElement scriptObject = (IHTMLScriptElement)doc.createElement("script");
scriptObject.type = @"text/javascript";
scriptObject.text = @"function btn1_OnClick(str){
    alert('you clicked' + str);
}";
((HTMLHeadElementClass)head).appendChild((IHTMLDOMNode)scriptObject);

Credo che il metodo più semplice per iniettare Javascript in un documento HTML di controllo WebBrowser da c # sia invocare il " execStrip " metodo con il codice da iniettare come argomento.

In questo esempio il codice javascript viene iniettato ed eseguito in ambito globale:

var jsCode="alert('hello world from injected code');";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });

Se vuoi ritardare l'esecuzione, inserisci le funzioni e chiamale dopo:

var jsCode="function greet(msg){alert(msg);};";
WebBrowser.Document.InvokeScript("execScript", new Object[] { jsCode, "JavaScript" });
...............
WebBrowser.Document.InvokeScript("greet",new object[] {"hello world"});

Questo è valido per i controlli Windows Form e WPF WebBrowser.

Questa soluzione non è cross-browser perché " execScript " è definito solo in IE e Chrome. Ma la domanda riguarda i controlli di Microsoft WebBrowser e IE è l'unico supportato.

Per un metodo cross-browser valido per iniettare codice javascript, creare un oggetto Funzione con la nuova parola chiave. Questo esempio crea una funzione anonima con codice iniettato e la esegue (javascript implementa le chiusure e la funzione ha accesso allo spazio globale senza inquinamento delle variabili locali).

var jsCode="alert('hello world');";
(new Function(code))();

Naturalmente, puoi ritardare l'esecuzione:

var jsCode="alert('hello world');";
var inserted=new Function(code);
.................
inserted();

Spero che sia d'aiuto

Ho usato questo: D

HtmlElement script = this.WebNavegador.Document.CreateElement("SCRIPT");
script.SetAttribute("TEXT", "function GetNameFromBrowser() {" + 
"return 'My name is David';" + 
"}");

this.WebNavegador.Document.Body.AppendChild(script);

Quindi puoi eseguire e ottenere il risultato con:

string myNameIs = (string)this.WebNavegador.Document.InvokeScript("GetNameFromBrowser");

Spero di esserti stato utile

Ecco un esempio di VB.Net se stai cercando di recuperare il valore di una variabile da una pagina caricata in un controllo WebBrowser.

Passaggio 1) Aggiungi un riferimento COM nel tuo progetto alla libreria di oggetti HTML Microsoft

Passaggio 2) Successivamente, aggiungi questo codice VB.Net al tuo Form1 per importare la libreria mshtml:
        Importa mshtml

Passaggio 3) Aggiungi questo codice VB.Net sopra il tuo " Public Class Form1 " Linea:
        & Lt; System.Runtime.InteropServices.ComVisibleAttribute (True) gt &;

Passaggio 4) Aggiungi un controllo WebBrowser al tuo progetto

Passaggio 5) Aggiungi questo codice VB.Net alla tua funzione Form1_Load:
        WebBrowser1.ObjectForScripting = Me

Passaggio 6) Aggiungi questo sub VB.Net che inietterà una funzione " CallbackGetVar " nel Javascript della pagina Web:

Public Sub InjectCallbackGetVar(ByRef wb As WebBrowser)
    Dim head As HtmlElement
    Dim script As HtmlElement
    Dim domElement As IHTMLScriptElement

    head = wb.Document.GetElementsByTagName("head")(0)
    script = wb.Document.CreateElement("script")
    domElement = script.DomElement
    domElement.type = "text/javascript"
    domElement.text = "function CallbackGetVar(myVar) { window.external.Callback_GetVar(eval(myVar)); }"
    head.AppendChild(script)
End Sub

Passaggio 7) Aggiungere il seguente sub VB.Net che Javascript cercherà quindi quando viene invocato:

Public Sub Callback_GetVar(ByVal vVar As String)
    Debug.Print(vVar)
End Sub

Passaggio 8) Infine, per invocare il callback Javascript, aggiungi questo codice VB.Net quando viene premuto un pulsante o dove preferisci:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    WebBrowser1.Document.InvokeScript("CallbackGetVar", New Object() {"NameOfVarToRetrieve"})
End Sub

Passaggio 9) Se ti sorprende che funzioni, potresti voler leggere su Javascript " eval " funzione, utilizzata nel passaggio 6, che è ciò che lo rende possibile. Prenderà una stringa e determinerà se esiste una variabile con quel nome e, in tal caso, restituisce il valore di quella variabile.

Puoi sempre usare un " DocumentStream " oppure " DocumentText " proprietà. Per lavorare con documenti HTML, consiglio un HTML Agility Pack .

Quello che vuoi fare è usare Page.RegisterStartupScript (chiave, script) :

Vedi qui per maggiori dettagli: http://msdn.microsoft.com /en-us/library/aa478975.aspx

Quello che sostanzialmente fai è costruire la tua stringa javascript, passarla a quel metodo e dargli un ID univoco (nel caso in cui provi a registrarlo due volte su una pagina.)

EDIT: questo è ciò che chiami trigger felice. Sentiti libero di farlo. :)

Uso questo:

webBrowser.Document.InvokeScript("execScript", new object[] { "alert(123)", "JavaScript" })

Se è necessario iniettare un intero file, è possibile utilizzare questo:

With Browser.Document
   Dim Head As HtmlElement = .GetElementsByTagName("head")(0)
   Dim Script As HtmlElement = .CreateElement("script")
   Dim Streamer As New StreamReader(<Here goes path to file as String>)
   Using Streamer
       Script.SetAttribute("text", Streamer.ReadToEnd())
   End Using
   Head.AppendChild(Script)
   .InvokeScript(<Here goes a method name as String and without parentheses>)
End With

Ricorda di importare System.IO per utilizzare StreamReader. Spero che questo aiuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top