This page shows a few examples of how you can interact with a web page using Python as the scripting language : create new elements, access and modify existing elements, create graphics, animations, send Ajax requests, etc.
The scripts use objects - elements shown in the page, styles applied to these elements, events, etc. - that are described in the Document Object Model (DOM), defined by the W3C. The reference used in this page is the Mozilla Developer Network (MDN) documentation.
Although the DOM is by nature language-independant, most examples in the MDN documentation are written with Javascript, not (yet ;-) in Python. The translation is usually straightforward, since Brython supports all the DOM types and their attributes and methods.
In some cases, Brython adds a more Pythonic syntax : you will discover them by browsing the examples.
More documentation and examples can be found on the Brython site.
browser
is a Brython-specific module that defines the objects
used to interact with the page.
document
is an object representing the HTML document ;
document[element_id]
is the element with attribute id equal
to element_id. In this example, document["button0"]
is a
reference to the button you click on.
bind(event, function)
is a method of elements that
takes two arguments, the name of an event and the function to call when
the event occurs on the element. When the user clicks on the element, this
event is called "click". The code means : when the user clicks on the
element (here, the button with the text "display an alert box"), call the
function hello
.
The function takes one argument, an object representing the event.
alert
is used to display small popup windows.
Instead of the browser alert box, you can use a dialog box provided
by the built-in module browser.widgets.dialog
.
Here, the box is positioned at the mouse position (given by the attributes
x
and y
of the event object) by keyword arguments
left
and top
.
The attributes and methods of the elements are described in the Document Object Model (DOM), which is abundantly documented (by Mozilla for instance).
textContent
is an attribute of
Node instances ; it is used to get or set an element's text content.
Brython supports all the DOM methods and attributes ; for text content
it provides a shortcut, text
, so that the function body can
also be written :
def change(event): document["zone1"].text = "New Content"
Elements have an attribute style
, which itself has (among many others) the attributes color
(text color), backgroundColor
(background color), fontWeight
("bold" or "normal"), fontSize
(size of the letters, in pixels), etc.
Look here for a reference on CSS.
Note that the attribute names that have a hyphen is CSS are written in camelCase in Python code : for instance, to set the CSS attribute background-color
, the syntax is style.backgroundColor
Elements have an attribute classList
with the values set in the attribute class
of the element.
It is an instance of the class DOMTokenList
, which supports the methods add()
and remove()
.
display
is another attribute of style
. Setting it to "none"
hides the element.
Note that in this example, we use a variant of the syntax to bind
events to functions. Instead of the form we had seen before, which uses
the method bind
of DOM elements, here we use the
function bind defined in module browser
. It is used
as a decorator for the callback function, and takes two parameters:
This example uses the standard DOM methods to create elements (document.createElement()
, createTextNode()
) and append them to other elements or to the document (Node.appendChild()
).
Note that on the last line, we use the standard DOM method EventTarget.addEventListener()
: the method bind()
used in the other examples is Brython-specific.
Also note the use of f-string for string formatting (PEP 448, introduced in Python 3.6) in the line
txt = document.createTextNode(f" {nb}")
To create DOM elements, Brython provides the module browser.html
. It defines classes with the name of all the valid HTML tags in uppercase ; html.B("message")
creates the element <B>message</B>
To include an element inside another one, Brython uses the operator <=
: think of it as a left arrow, not as "less than or equal". The use of an operator is more concise and avoids having to use a function call.
We use the standard DOM method insertBefore()
and insert the element after element.nextSibling.
If the element is the last in its parent's children, nextSibling
is null
so the new element is inserted at
the end.
The attributes of a tag are defined as keyword arguments of the html classes constructor.
Note that the style attribute is passed as a dictionary ; also note that, since class
is a Python keyword, it can't be used as a key, so we use Class
instead (tag attributes are case-insensitive).
To build a table, we use the HTML tags TABLE, TR, TH
and TD
.
The first attribute passed to the classes defined in browser.html
is either a string, another instance of a class, or an iterator on such elements.
Here we use a Python generator expression to include several headers (TH
) in the first row (TR
) of the table, and the same for the table cells (TD
) in the next rows.
clear()
is a method that removes all the element contents.
We build the dropdown menu by a SELECT element, using a generator expression with the OPTION elements displayed in the menu.
When the user changes the selected option in the menu, the event "change" is triggered on the SELECT box. This is done in the line
dropdown.bind("change", show)
In function show(event)
, event.target
is the element itself.
A SELECT element has an attribute selectedIndex
, the rank of the selected item in the list of options, available by its attribute options
. The OPTION element itself has an attribute value
, here the option text.
We start by importing the module math
, the same as in the Python standard distribution.
Canvas is an API for drawing geometric forms in the page. The examples on the MDN pages are written in Javascript but can be easily translated for Brython.
Checkbox
We have seen how to get an element by its id : document[element_id]
. Here, document["zone13"]
is the bordered box at the right of the button.
The method select(css_selector)
provides a way to select elements based on the CSS selector syntax. Passing the name of a tag returns a list of all the elements with this tag ; passing .zone
returns a list of all the elements whose attribute class
is set to "zone"
.
transform
is another attribute of style
that can make changes to the element, including a rotation by a specified angle.
The browser window provides 2 functions to start and stop an animation : requestAnimationFrame
and cancelAnimationFrame
.
When the user clicks on the button, the animation is started by calling the function animloop
with an arbitrary argument. window.requestAnimationFrame
, called with the function itself as argument, returns a reference to the animation. The drawing function, render()
is called ; the loop is then executed repeatedly under the control of the animation loop.
In render()
, to put the element at a specific location, we use another transform
function, translate(x, y)
. The moving element bounces, and its shape changes, when its position reaches the box borders.
If the user clicks the button again, calling window.cancelAnimationFrame
on the animation object stops the animation.
This example uses other mouse events than "click" : "mousedown", "mousemove" and "mouseup".
The mouse position is available by the attributes x
, y
of the event object.
The position of an element can be changed by defining its attributes left
and top
.
The Storage API allows local storage of key/value pairs.
Notice the use of method elt.closest(tagName)
to get the first DOM element with the specified tag name above elt
.
The event "change" on the INPUT field is triggered when the field loses focus, if the value has been modified.
Warning: this demo only works if this page (demo.html) is served in http, not https.
The module browser.ajax
allows sending Ajax calls, ie sending HTTP requests to a URL and handle the reply without having to reload the page.
Here we use a public API that gives the current position of the International Space Station. The callback function complete()
is called when the Ajax call has completed ; its argument has an attribute responseText
, the response sent by the server. In this case, the API tells us that it's a JSON string. We decode it with the module json
of the standard distribution.
This example is a minimalist text editor : it shows how to select a local file in the user's machine, display its content in a TEXTAREA, and save the TEXTAREA content to disk.
It uses the interface File of the DOM API.
The "save" button must be an anchor (HTML tag A) with attribute "download" set.
By default, print()
writes message in the browser console window (to open it, right-click on the page, and click the "Inspect Element" button.
Safari users cannot see this option initially.).
Like in Python, the output can be reset by setting sys.stdout
to an object with a method write()
.
Instead of using the XML modules in Python standard library, it's more efficient to use the Web API DOMParser to parse XML documents.
Brython provides the modules time
and
datetime
of the standard distribution, but it
can also interact with the objects defined by Javascript.
To use such objects, import the module javascript
:
it is used to get a reference objects defined by the Javascript language.
Because the Javascript object Date
is a constructor (ie a function that returns new objects with the syntax
var date = new Date()), we create Brython objects with the
attribute new
.
We then use the attributes of the Javascript instance of
Date()
such as getFullYear
with the usual Python syntax.