Basic Webpage Controls with JavaScript / COMThis tutorial requires one of the following:
PurposeThe purpose of this tutorial is to teach the intermediate AHK user how to
start using COM to control webpages. My goal is to provide methods for controlling webpages, similar to how the AHK Control Commands can control Windows Applications. This tutorial is going to be high level, but will provide links to those who want to dig deeper into these concepts. You don't need to have much programming experience, but I will assume you feel comfortable writing and executing AHK scripts. We will be covering the following three topics:
- The HTML DOM - (Document Object Model) A basic understanding of the HTML DOM is essential for controlling webpages. This is because it's a "map" or "heirarchy" for accessing parts of the webpage. The HTML DOM is not language dependent, but rather the model for how the webpage document is constructed.
- JavaScript - We will cover some basic JavaScript because it is the scripting language of the web, and is supported by most web browsers. Controlling webpages using JavaScript is not the primary aim of this tutorial, but it will prove valuable because you should be able to find plenty of useful JavaScript examples online. This will be helpful because in my opinion, the simplest way to start using COM is to learn some basic JavaScript, and then "translate" that code to use with COM in AHK.
- COM - (Component Object Model) All you really need to know about COM for this tutorial is that Internet Explorer is a COM object - which means we can use COM to manipulate it. Using COM is the most effective way to control an Internet Explorer Webpage with AHK.
"Let me say it a different way: COM is the steering wheel - the HTML DOM is a road map - AHK is the car" ~tankDisclaimersFor this tutorial, I will show you how to control webpages using JavaScript, along with the AHK COM "translations" (AutoHotkey_L in
Black,
AHK Basic in Green) -
also, note Sean's post below. (Using COM requires Internet Explorer, but JavaScript can be used with most Web Browsers) The guidelines for "translating" JavaScript can be found in the first post of the
COM Standard Library thread
(for AHK Basic).
Color Legend wrote:
Javascript: dark blue
AutoHotkey_L: black
AHK Basic: green
Some other tutorials that helped me out, and inspired this tutorial can be found here:
- COM Tutorial by tank - Study the basics from this; I will not be covering them.
- W3Schools - Many links listed below will take you to this website, which is an excellent resource for learning JavaScript in depth.
Thank You:
- Chris Malet for creating AutoHotkey
- Lexikos for AutoHotkey_L
- Sean & fincs for helping with Native COM Support
- Sean for creating the COM Standard Library
- tank for the tutorial listed above, & daonlyfreez
- tank, sinkfaze, & jaco0646 for reviewing this tutorial
Terms - The following terms will be used throughout this tutorial. You may use these links for a more in-depth description of each item.
HTML DOM,
JavaScript,
COM,
Methods,
document,
value,
element,
form,
name,
ID,
Input,
Tag,
selectedIndex,
checked,
innerText,
innerHTMLMethods - The following Methods will be used throughout this tutorial. (comparable to built-in functions for AHK)
alert(),
getElementById(),
getElementsByName(),
getElementsByTagName(),
focus(),
click()Before we begin, this tutorial will be using examples that start with
javascript: - which
you will feed through the URL Address bar. These examples will be based on (and can be used with) the
Search Forum webPage. Our first example will use the alert() method to pop-up a message box that says
Hello World! Simply put this javascript in your URL Address bar and hit enter:
Code:
javascript: alert('Hello World!')
WB.Navigate("javascript: alert('Hello World!')")
COM_Invoke(pwb, "Navigate", "javascript: alert('Hello World!')")
Accessing WebPage Contents - HTML DOMTo understand how to use Javascript to control a webpage, you need a general understanding of the HTML DOM. It is similar to a "map" or "heirarchy" of the Webpage, as shown here:
*Image is from this website, which is another great resource for learning Javascript.
In the image above, note the
document object - you will be using this object quite often. To access the Webpage, you will need to navigate through the HTML DOM. Here are some simple ways to do this:
- Object Name & Index
Say you want to get the value of the 1st element in the 1st form, which will be the Search for Keywords Input Box. The path would look like this (a collection of objects starts at 0): Code:
document.forms[0].elements[0].value
Now if you want to show the value of the element in a pop-up, simply put this javascript in your URL Address bar and hit enter: Code:
javascript: alert(document.forms[0].elements[0].value)
MsgBox % WB.document.forms[0].elements[0].value
MsgBox % COM_Invoke(pwb, "document.forms[0].elements[0].value")
- Object's Name / ID Attribute
You can also use the objects name or ID. For example, the 1st forms name is SearchForm, with its 1st elements name being search_keywords. The following javascript fed throught the address bar would produce the same results:Code:
javascript: alert(document.SearchForm.search_keywords.value)
MsgBox % WB.document.SearchForm.search_keywords.value
MsgBox % COM_Invoke(pwb, "document.SearchForm.search_keywords.value")
Or if you only know the elements name is search_keywords, you could display the value of that element using all, which references all the elements on the webpage:Code:
javascript: alert(document.all.search_keywords.value)
MsgBox % WB.document.all.search_keywords.value
MsgBox % COM_Invoke(pwb, "document.all.search_keywords.value")
- getElement Methods
If you want to get an element(s) based on limited criteria, you can use the following 3 methods:- getElementById(id) - returns a reference to the first object with the specified ID
- getElementsByName(name) - Returns a collection of objects with the specified name
- getElementsByTagName(tagname) - Returns a collection of objects with the specified tagname
The following example will display the value of the Search for Author Input Box, which is the 4th element on the webpage with an INPUT Tag:
(Note - the item number may be dynamic)Code:
javascript: alert(document.getElementsByTagName('input')[3].value)
MsgBox % WB.document.getElementsByTagName("input")[3].value
MsgBox % COM_Invoke(pwb, "document.getElementsByTagName[input].item[3].value")
Controlling the WebPageSo far we have just retrieved information from the webpage. Now lets start controlling the webpage.
Note - if the JavaScript doesn't end with a Method, use
void 0.
- Focus on a Webpage Element - focus()
Sets the focus to the Search for Keywords Input Box:Code:
javascript: document.all.search_keywords.focus()
WB.document.all.search_keywords.focus()
COM_Invoke(pwb, "document.all.search_keywords.focus")
- Click on a Webpage Element - click()
Clicks the Search button:Code:
javascript: document.getElementsByTagName('input')[11].click()
WB.document.getElementsByTagName("input")[11].click()
COM_Invoke(pwb, "document.getElementsByTagName[input].item[11].click")
- Set Value of an Input Field - value
Sets the value of the Search for Keywords Input Box:Code:
javascript: document.all.search_keywords.value = 'Input Value'; void 0
WB.document.all.search_keywords.value := "Input Value"
COM_Invoke(pwb, "document.all.search_keywords.value", "Input Value")
- Dropdown Box Selection - selectedIndex
Quote:
<SELECT class=post name=sort_by><OPTION selected value=0>Post Time</OPTION><OPTION value=1>Post Subject</OPTION><OPTION value=2>Topic Title</OPTION><OPTION value=3>Author</OPTION><OPTION value=4>Forum</OPTION></SELECT>
This is the HTML for the Sort By Dropdown. The following will set the Dropdown to Author:Code:
javascript: document.all.sort_by.selectedIndex = 3; void 0 ; Note - you could use value = 3
WB.document.all.sort_by.selectedIndex := 3
COM_Invoke(pwb, "document.all.sort_by.selectedIndex", 3)
- Radio / Checkbox Selection - checked
Quote:
<INPUT value=ASC type=radio name=sort_dir> Ascending<BR><INPUT value=DESC CHECKED type=radio name=sort_dir> Descending
This is the HTML for the Sort By Radio selection. The following will set the Radio to Ascending: Code:
javascript: document.all.sort_dir[0].checked = true; void 0
WB.document.all.sort_dir[0].checked := True
COM_Invoke(pwb, "document.all.sort_dir[0].checked", True)
- Get Text from a WebPage Element - innerText
Say you want to get the text at the top of the page (innerHTML will give you all the HTML):Code:
text := WB.document.getElementsByTagName("TD")[2].innerText
text := COM_Invoke(pwb, "document.getElementsByTagName[TD].item[2].innerText")
... or if you want all the text (or html) from the page:Code:
text := WB.document.documentElement.innerText
text := COM_Invoke(pwb, "document.documentElement.innerText")
There you have it! These techniques should help get you
started. Next, I would recommend the following:
- Try these Controls out on some of your favorite webpages.
- Find some more JavaScript examples, and then try "translating" them to COM. (JavaScript is well documented online)
- Learn additional ways to access the HTML DOM.
You may be wondering,
"How do I find information about the element so I can access it?" Good question! The following tools can help you with that.
Helpful Tools- iWebBrowser2 Learner - This program will give you information about IE webpage elements as you hover over them.
- IE HTML Element Spy - This program will show you the information and source code of each element by dragging the curser over the webpage.
Frequently Asked QuestionsWhat is a WB/pwb? - An object/variable that contains a
pointer to the
Web
Browser object
(Internet Explorer). Here is a simple script for creating one:
Code:
; AutoHotkey_L:
WB := ComObjCreate("InternetExplorer.Application") ; Create an IE object
WB.Visible := true ; Make the IE object visible
WB.Navigate("www.AutoHotkey.com") ; Navigate to a webpage
Code:
; AHK Basic:
COM_Init() ; Initialize COM
pwb := COM_CreateObject("InternetExplorer.Application") ; Create an IE object
COM_Invoke(pwb, "Visible=", true) ; Make the IE object visible
COM_Invoke(pwb, "Navigate", "www.AutoHotkey.com") ; Navigate to a webpage
; when finished
COM_Release(pwb) ; Always release COM objects
COM_Term() ; Always Uninitialize COM
How to access an existing IE object?- Access an IE object by WinTitle & Internet Explorer_Server Number:
- Access an IE object by Window/Tab Name:
How to know when the webpage in done loading?- Sean's
IEReady() function is great for this, and can be found
here. Here is an example using the
ReadyState property, which should work in may scenarios:
Code:
; AutoHotkey_L:
WB.Navigate("www.AutoHotkey.com")
while, WB.ReadyState != 4
; while, WB.Busy
Sleep, 10
Code:
; AHK Basic:
COM_Invoke(pwb, "Navigate", "www.AutoHotkey.com")
while, COM_Invoke(pwb, "ReadyState") != 4
; while, COM_Invoke(pwb, "Busy")
Sleep, 10
-
OR - here is an example using the
DocumentComplete event:
Code:
; AutoHotkey_L:
WB := ComObjCreate("InternetExplorer.Application")
WB.Visible := True
ComObjConnect(WB, "IE_"), loading := true ; Connect IE object & set var "loading" as TRUE
WB.Navigate("www.AutoHotkey.com")
while, loading
Sleep, 10
MsgBox, DONE!
WB := "" ; Release & Disconnect IE object
return
IE_DocumentComplete() { ; the "IE_" prefix corresponds to the ComObjConnect() function above
global loading := false ; Break the While-Loop
}
Code:
; AHK Basic:
COM_Init()
pwb := COM_CreateObject("InternetExplorer.Application")
COM_Invoke(pwb, "Visible=", "True")
sink := COM_ConnectObject(pwb, "IE_"), loading := true ; Connect IE object & set var "loading" as TRUE
COM_Invoke(pwb, "Navigate", "www.AutoHotkey.com")
while, loading
Sleep, 10
MsgBox, DONE!
COM_DisconnectObject(sink) ; Disconnect IE object
COM_Release(pwb), COM_Term()
return
IE_DocumentComplete() { ; the "IE_" prefix corresponds to the COM_ConnectObject() function above
global loading := false ; Break the While-Loop
}
What if all this stuff is too confusing for me?