Brython -Python in the Browser: Elements and Events
I am something of a fan of Brython. It is essentially Javascript in a different form, but for someone who is used to python and its formatting, coding in a Python is dreamy.
One of the complaints I hear is that Brython is not 100% Python and you need to know a lot about the front end to use it. My answer is that of course you do. If your coding to use a database, you need to understand the database to be able to use it properly using python, so to write code that effects the DOM, you need to understand the DOM.

DOM API
Brython links to the DOM API, not to the Javascript API. This is an important thing to know. This also means that you need to have a good feel for the DOM API, especially Elements and Events. You need these as basics to be able to code in the frontend.
Elements are sort of objects and they are an Instance of an Element Type. You will notice the documentation doesn’t really like to talk in OOP language, but it kinda follows the same principles. So an element is some part of the page. and usually corresponds to html tags.
Getting an Element
The easiest way to get an element is by its id, that’s the one you attached to the html tag.
from browser import document
element = document["element_id"]Brython has other ways to find elements. They are partially documented, but not really explained. This other way uses what are called css selectors. They allow you to define a very complex pattern to your element. Check out the link on the selectors, but here is how to use them.
from browser import document
list_of_elements = document.select(".class1.class2")
one_element = document.select_one("#element_id") # same as document['myelement']CSS selectors are a great way of finding elements in a page.
Element Properties
The Brython documentation mentions some properties, but not all. From uses so far, the Brython document has access to most of the properties and methods defined for a Dom Element. For more specialized elements, check out the DOM Element that is specific for that, such as the Select Element.
The Brython document class has a few special methods, but it makes more sense to follow the DOM on this. Here is an example of adding a css class to an element
from browser import document
element = document['myelement']
element.classList.add("new_class")“classList” is an attribute documented in the DOM documentation, but I’ve not seen it in the Brython one. This proves my point in that you need to understand the DOM as well as Brython.
Specialized Elements
Lets take a look at the Select Element I mentioned earlier. In the Select Element documentation, you will find a few differences from the standard one. There is one difference for Brython though. It changes the “options” property into a list. Thus you can insert() and append() options to the select item. The DOM would require the creation of Option objects etc.
Listening for Events
Your page is like any UI and you need to link your code to an element in the UI, or more specifically to events that happen to that element. Here is a list of events that can occur. This is called binding by the way.
Binding to multiple elements
This is a little backwards, but you will get why.
For any binding, you take one or more elements , and event and a function or method. Here is an example of binding to multiple elements.
from browser import bind
@bind(".aclass", "click")
def do_something(event):
print("hey trigged by a click")So I showed this one first because you need to understand the process flows. The Decorator here is only run when the code is initialized. It will search the DOM, find the elements and create a series of binds between the element, event and the function. So what happens if you change the page, such as adding in a new element that has a css class of “aclass”? Well its NOT bound to the function. The decorator has already run and done its job. Adding in elements later will not mean they are automatically bound using this method.
Binding via the Decorator to a single element
from browser import document, bind
element = document["myelement"]
@bind(element, "click")
def do_something(event):
print("myelement was clicked")This works ok, but really if we are looking a DRY, this would not be the best option.
Document Binding
from browser import document, bind
def do_something(event):
print("I was clicked")
element = document["myelement"]
element.bind("click", do_something)
class MyElement:
def __init__(self):
self.element = document["myelement"]
self.element.bind("click", self.do_something)
def do_something(self, event):
print("I was clicked")
class MyElement2:
def __init__(self):
self.element = document["myelement"]
@bind(self.element, "click")
def do_something(self, event):
print("this is possible, but not very pyronic") So here are some examples of binding to a single document, both to a function and to methods in a class. I think using the bind decorator on a method in a class is not the right way to do, but you can.
Quick word on Event target
I don’t quite understand why this is, but Event instances have .target and .currentTarget properties. Use .currentTarget as the other usually holds a different element than the one you bound. If your using something like the classes I showed above, use the class element property instead of the element in the event to make sure you get the right one.
As I said, not an expert here, so I don’t quite get this one, but I know there can be issues and this is how you get around them.
Final Words
I feel SOOOO much better using Brython instead of Javascript, but I do keep my scripts small and uncomplicated. I’m not looking to build a front end framework in Brython. The documentation is ok, but it doesn’t really scream that you need to understand the DOM API and you kinda do
