I'm looking for a way to get the JavaScript code defined inside of onclick. I'm using .NET 2.0 C# Visual Studio 2005.
Example:
<span id="foo" onclick+"window.location.href='someURL'>click here</span>
My goal is to get the string "window.location.href='someURL'".
Scenario:
A user clicks on web page element, the tag shown above for instance, inside of WebBrowser control. Then the clicked tag is refereed to HtmlElement object
.
In WebBrowser control I then call HtmlElement object's getAttribute("onclick")
, it just gives me "System.__ComObject".
I've searched how to deal with it then found that it can be casted then get the value.
if (tag.GetAttribute("onclick").Equals("System.__ComObject"))
{
Console.WriteLine("dom elem >>>>>>>>>>> " + tag.DomElement.ToString());
mshtml.HTMLSpanElementClass span = (mshtml.HTMLSpanElementClass)tag.DomElement;
Console.WriteLine("js value ===>" + span.onclick);
}
Output:
dom elem >>>>>>>>>>> mshtml.HTMLSpanElementClass
js value ===> System.__ComObject
As it shown, span.onclick still give me System.__ComObject, what am I doing wrong?
In Why does HtmlElement's GetAttribute() method return “mshtml.HTMLInputElementClass” instead of the attribute's value? this guy said it worked in his case, and I've followed it, but mine is somewhat not working...
UPDATE
Research, research.....
I can add reference VisualBasic.dll to my C# project then call the method to find out who is this System.__ComObject really is.
Console.WriteLine(Microsoft.VisualBasic.Information.TypeName(span.onclick));
Output:
JScriptTypeInfo
It looks like this is a JScript type... how can I access this object?
More detail
The above description is based on my current project. The project is to create something like Selenium IDE. It uses WebBrowser control instead.
Selenium IDE creates 3 different things to record an element in the web document.
1. actionType
2. xpath
3. value
For instance,
type, //input[@id=foo], "hello world"
clickAndWait, //link=login, ""
Selenium IDE recognize page load so it changes actionType between "click"
and "clickAndWait"
. My case, I want to make it simple.
If I click on the element and if it is anchor tag
or has page load kind of javascript
such as onclick=window.location.href='blah'
then I want to set the actionType to "clickAndWait"
.
There are number of ways you can do it.
- There is an Event object in DOM, which will give you information about which element generated this event.
- You can look at here, http://msdn.microsoft.com/en-us/library/ff975965%28v=VS.85%29.aspx
- This one is good, you can use this easily, you will get the event object as method parameter which you can investigate parameters to find out the source of the event. http://support.microsoft.com/kb/312777
Another alternative is to use a custom navigation url and act upon it
- Override BeforeNavigate event
- Check for Navigation url if it contains "mycommand:click" or "mycommand:clickandwait" 3. If it contains any of this, then set cancel as true. (this will stop navigation by browser).
- Then you can navigate your webbrowser code from your C# code and pass cancel as true.
Another Alternative method is to use External object, WebBrowser allows you to set an ObjectForScripting which you can access within Javascript of HTML.
ObjectForScripting in .NET 2.0
[ComVisible(true)]
public class MyClass
{
// can be called from JavaScript
public void ShowMessageBox(string msg){
MessageBox.Show(msg);
}
}
myBrowser.ObjectForScripting = new MyClass();
// or you can reuse instance of MyClass
And you can call,
window.external.ShowMessageBox("This was called from JavaScript");
Cast the element object to mshtml.IHTMLDOMNode, then read the attributes via IHTMLDOMNode.attributes. HtmlElement.GetAttribute is getting the IDispatch interface of the jscript function generated from the embedded attribute.
You can try to parse webBrowser1.DocumentText
property using HtmlAgilityPack and then get desired result using XPath.
If you don't HAVE to do it with C# (you can do it with JS and create a Postback) you should take a look at THIS question.
As per Sheng Jiang's response, here is some working sample:
IHTMLElement element = YourCodeToGetElement();
string onclick = string.Empty;
IHTMLDOMNode domNode = element as IHTMLDOMNode;
IHTMLAttributeCollection attrs = domNode.attributes;
foreach (IHTMLDOMAttribute attr in attrs)
{
if (attr.nodeName.Equals("onclick"))
{
string attrValue = attr.nodeValue as string;
if (!string.IsNullOrEmpty(attrValue))
{
onclick = attr.nodeValue;
break;
}
}
}
You can parse it yourself easily, by first reading obj.outerHtml. That should give you the entire html for that obj, then search it for the value onclick="????" and extract the ???? part.
来源:https://stackoverflow.com/questions/6223840/how-to-get-actual-javascript-value-in-onclick-from-webbrowser-control