Curso de Brython en Español - Acceso y manipulación del DOM
Introducción
En este capítulo aprendenrás a acceder y manipular las etiquetas html desde código brython.
En esta sección trabajaremos con el siguiente documento html:
<!--index.html-->
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ACCESO / MANIPULACIÓN DOM</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js"></script>
</head>
<body onload="brython()">
<h1 id="titulo">Título del Documento</h1>
<h2 id="subtitulo">Subtítulo del Documento</h2>
<ul id="lista"></ul>
<script type="text/python">#codigo-python</script>
</body>
</html>
Escribiremos el código python donde pone #codigo-python
. Si lo prefieres puedes enlazar con un archivo externo tal y como hicimos en el capítulo anterior.
¡¡ Comenzemos !!
Acceder a los elementos del DOM
Fíjate en index.html. Hay una serie de etiquetas a las que he asignado un atributo id. Puedes acceder a estas etiquetas así:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
lista = document['lista']
Por ejemplo, para mostrar el texto del título en un alert
:
from browser import document, alert
titulo = document['titulo'] # También puedes usar document.getElementById('titulo')
alert(f'El título es "{titulo.text}"') # También puedes usar titulo.textContent
La variable titulo
hace referencia a la etiqueta h1 con id="titulo". Puedes acceder a cualquiera de sus atributos. Otra forma de hacer lo mismo sería utilizando document.getElementById
, que es la forma habitual de hacerlo en javascript. Del mismo modo, puedes utilizar indistintamente .text
o .textContent
para obtener el texto del elemento.
Puedes acceder a cualquier elemento del documento que tenga su atributo id definido:
from browser import document, alert
titulo = document['titulo']
subtitulo = document['subtitulo']
for i in titulo, subtitulo:
alert(f'El {i.id} es "{i.text}"')
En este caso mostramos un alert
para titulo
y otro para subtitulo
. En ambos casos obtenemos sus atributos .id
y .text
para crear la alerta adecuada.
Esto está bien, pero te resultará mas interesante manipular el texto de los elementos desde python.
Manipular los elementos del DOM
Vamos a modificar el título y subtítulo de las etiquetas html / elementos del DOM. Por ejemplo, si queremos que la etiqueta h1 con id="titulo" muestre el texto "Mi lista de la compra":
from browser import document
titulo = document['titulo']
titulo.text = 'Mi lista de la compra'
Tan sencillo como asignar un nuevo valor a la propiedad titulo.text
. Ya que estamos modifiquemos también el subtítulo:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
titulo.text = 'Mi lista de la compra'
subtitulo.text = 'Toma nota de mi lista de la compra:'
En index.html tenemos una etiqueta ul con id="lista". La lista está vacía, pero vamos a rellenarla ahora mismo.
En este caso, en lugar de modificar el valor de la propiedad .text
vamos a utilizar la propiedad .html
para que el texto asignado sea interpretado como código html:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
lista = document['lista']
titulo.text = 'Mi lista de la compra'
subtitulo.text = 'Toma nota de mi lista de la compra:'
lista.html = '<li>Pan</li><li>Huevos</li><li>Jamón</li><li>Cebolla</li>' # También puedes usar lista.innerHTML
En brython, la razón por la que puedes utilizar .text
o .textContent
para acceder al texto, y .html
o .innerHTML
, es la primera forma es mas pythonica. En javascript solamente existen .textContent
e .innerHTML
para acceder al texto y html respectivamente.
Ahora que hemos añadido una serie de elementos li
a la lista ¿cómo acceder a ellos?. Podrías asignar un atributo id a cada uno de ellos. Por ejemplo, vamos a acceder al primer li
y vamos a cambiar su texto:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
lista = document['lista']
titulo.text = 'Mi lista de la compra'
subtitulo.text = 'Toma nota de mi lista de la compra:'
lista.html = '''
<li id="pan">Pan</li>
<li>Huevos</li>
<li>Jamón</li>
<li>Cebolla</li>
'''
document['pan'].text += ' Tostado'
Sin embargo no es necesario asignar un id siempre. Puedes acceder a los hijos de un elemento según su posición. Por ejemplo:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
lista = document['lista']
titulo.text = 'Mi lista de la compra'
subtitulo.text = 'Toma nota de mi lista de la compra:'
lista.html = '''
<li>Pan</li>
<li>Huevos</li>
<li>Jamón</li>
<li>Cebolla</li>
'''
lista.children[0].text += ' Tostado'
lista.children[-1].text += ' Caramelizada'
En brython, todos los elementos html tienen un atributo children
que es una lista posicional de los elementos que contiene.
También puedes iterar sobre el ul
para acceder a cada uno de sus hijos:
from browser import document
titulo = document['titulo']
subtitulo = document['subtitulo']
lista = document['lista']
titulo.text = 'Mi lista de la compra'
subtitulo.text = 'Toma nota de mi lista de la compra:'
lista.html = '''
<li>Pan</li>
<li>Huevos</li>
<li>Jamón</li>
<li>Cebolla</li>
'''
for i in lista:
i.text = i.text.upper()
for i in lista.children:
i.text += ', delicioso!'
Ahora todos los elementos de la lista aparecen en mayúsculas y son deliciosos!!
Fíjate en que, para iterar sobre los hijos de un elemento, puedes iterar directamente sobre el elemento padre: for i in lista
o sobre su atributo children
: for i in lista.children
. El resultado es el mismo.
Otras formas de acceder a elementos del DOM
En esta sección utlizaremos el siguiente archivo html.
<!-- otras formas de acceder a elementos del DOM -->
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8"/>
<title>OTRAS FORMAS ACCESO DOM</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js"></script>
</head>
<body onload="brython()">
<p>Párrafo 1</p>
<p>Párrafo 2</p>
<p>Párrafo 3</p>
<div id="contenedor">
<p>Párrafo en contenedor 1</p>
<p>Párrafo en contenedor 2</p>
<p>Párrafo en contenedor 3</p>
</div>
<script type="text/python">#codigo-python</script>
</body>
</html>
Acceder al div con id="contenedor"
from browser import document, alert
contenedor = document['contenedor']
alert(f'El contenedor tiene {len(contenedor.children)} elementos')
Se obtendría el mismo resultado con:
contenedor = document.getElementById('contenedor')
contenedor = document.select_one('#contenedor')
contenedor = document.querySelector('#contenedor')
Acceder a todos los párrafos
from browser import document
parrafos = document.select('p')
for p in parrafos:
p.style.color = 'red'
Se obtendría el mismo resultado con:
parrafos = document.querySelectorAll('p')
parrafos = document.getElementsByTagName('p')
Acceder sólo a los párrafos dentro del div
from browser import document
parrafos = document.select('#contenedor > p')
for p in parrafos:
p.style.color = 'red'
Se obtendría el mismo resultado con:
parrafos = document.select('div > p')
- Ya que solo hay un div.parrafos = document.querySelectorAll('#contenedor > p')
parrafos = document.querySelectorAll('div > p')
- Ya que solo hay un div.parrafos = document['contenedor'].select('p')
parrafos = document['contenedor'].querySelectorAll('p')
parrafos = document['contenedor'].getElementsByTagName('p')
Acceder sólo a los párrafos fuera del div
from browser import document
parrafos = document.select('p:not(#contenedor > p)')
for p in parrafos:
p.style.color = 'red'
Otra forma sería la siguiente:
from browser import document
parrafos = document.select('p')
contenedor = document['contenedor']
parrafos_fuera = [p for p in parrafos if p.parent != contenedor]
for p in parrafos_fuera:
p.style.color = 'red'
Puedes usar .parent
o .parentNode
para referirte al padre del elemento. La segunda forma es como se haría en javascript.
En el próximo capítulo veremos cómo crear elementos html dinámicamente desde código python para añadirlos al documento, pero de momento no he tenido tiempo de escribir mas. Espero hacerlo pronto!!