Brython 将点击事件绑定到页面中尚不存在的 id
Brython bind a click event to an id that is not yet in the page
所以我有以下困境:
我正在使用 Brython,一切正常。我有一小段代码可以为我执行 ajax 请求,我在 header 中添加了它以绑定页面中当前元素上的所有内容。
from browser import document, ajax
# URL Query String
qs = ''
# URL to work on
url = ''
def post_data(url, qs):
req = ajax.ajax()
# Bind the complete State to the on_post_complete function
req.bind('complete', on_post_complete)
# send a POST request to the url
req.open('POST', url, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
# send data as a dictionary
req.send(qs)
def get_data(url, qs):
req = ajax.ajax()
req.bind('complete', on_get_complete)
# Bind the complete State to the on_get_complete function
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def on_post_complete(req):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
else:
document["main_area"].html = "error " + req.text
def on_get_complete(req):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
else:
document["main_area"].html = "error " + req.text
def account_click(ev):
get_data("/account", qs)
def contact_link_click(ev):
get_data("/contact", qs)
def logo_link_click(ev):
get_data("/main_page", qs)
def products_link_click(ev):
get_data("/products_page", qs)
def register_link_click(ev):
get_data("/register", qs)
document['login_link'].bind('click', account_click)
document['contact_link'].bind('click', contact_link_click)
document['logo_link'].bind('click', logo_link_click)
document['register_link'].bind('click', register_link_click)
document['running_link'].bind('click', products_link_click)
document['fitness_link'].bind('click', products_link_click)
document['tennis_link'].bind('click', products_link_click)
document['football_link'].bind('click', products_link_click)
document['golf_link'].bind('click', products_link_click)
现在我更大的问题是 register_link
从一开始就不在页面中。更确切地说,register_link
只会在 login_link
link 被点击后加载到 DOM 中,之后寄存器 link 什么都不做,因为事件无法从一开始就绑定它。
现在我知道我可以通过在该页面中再次导入它来轻松绕过它,但我想避免冗余导入,我不太确定具体如何去做。
编辑:
或者在 brython 中有没有办法等待 DOM 完全加载?
这不是常识不能为你工作的 - Brython 在这方面与 Javascript 一样:任何你想要更改的 DOM 元素都需要在你尝试之前存在到 modify/bind 它。
几十年来,"usual" 在 Javascript 中实现这一点的方法一直是将绑定放在一个函数中,然后在页面底部或 body
上调用它标记 onload
事件,在加载其他所有内容之后。 "Modern" Javascript 使用 jQuery 或其他框架及其 ready()
方法对 "solves" 进行编码。
你必须在那里做同样的事情 - 计时器可能会工作,但有风险。当然,触发一个或多个其他函数后才存在的元素应该在各自的函数中处理:
def account_click(ev):
get_data("/account", qs)
document['register_link'].bind('click', register_link_click)
如您所见,account_click
是这样写的:
def account_click(ev):
get_data("/account", qs)
document['register_link'].active = True
document['register_link'].bind('click', register_link_click)
不起作用,因为程序不会等待 get_data
完成后再执行接下来的两行。
一个解决方案是为这种情况编写特定版本的 get_data
和 on_get_complete
(我假设 "register_link" 按钮在页面中,但最初是禁用的):
def complete_register(req):
"""Called when the Ajax request after "login_link" is complete."""
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
# enable "register link" button and add binding
document['register_link'].disabled = False
document['register_link'].bind('click', register_link_click)
else:
document["main_area"].html = "error " + req.text
def get_data_and_register(url, qs):
req = ajax.ajax()
req.bind('complete', complete_register)
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def account_click(ev):
get_data_and_register("/account", qs)
另一种选择是保留通用函数 get_data
和 on_get_complete
,并添加一个可选参数 callback:
def get_data(url, qs, callback=None):
req = ajax.ajax()
req.bind('complete', lambda req:on_get_complete(req, callback))
# Bind the complete State to the on_get_complete function
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def on_get_complete(req, callback=None):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
if callback is not None:
callback(req)
else:
document["main_area"].html = "error " + req.text
所以我有以下困境:
我正在使用 Brython,一切正常。我有一小段代码可以为我执行 ajax 请求,我在 header 中添加了它以绑定页面中当前元素上的所有内容。
from browser import document, ajax
# URL Query String
qs = ''
# URL to work on
url = ''
def post_data(url, qs):
req = ajax.ajax()
# Bind the complete State to the on_post_complete function
req.bind('complete', on_post_complete)
# send a POST request to the url
req.open('POST', url, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
# send data as a dictionary
req.send(qs)
def get_data(url, qs):
req = ajax.ajax()
req.bind('complete', on_get_complete)
# Bind the complete State to the on_get_complete function
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def on_post_complete(req):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
else:
document["main_area"].html = "error " + req.text
def on_get_complete(req):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
else:
document["main_area"].html = "error " + req.text
def account_click(ev):
get_data("/account", qs)
def contact_link_click(ev):
get_data("/contact", qs)
def logo_link_click(ev):
get_data("/main_page", qs)
def products_link_click(ev):
get_data("/products_page", qs)
def register_link_click(ev):
get_data("/register", qs)
document['login_link'].bind('click', account_click)
document['contact_link'].bind('click', contact_link_click)
document['logo_link'].bind('click', logo_link_click)
document['register_link'].bind('click', register_link_click)
document['running_link'].bind('click', products_link_click)
document['fitness_link'].bind('click', products_link_click)
document['tennis_link'].bind('click', products_link_click)
document['football_link'].bind('click', products_link_click)
document['golf_link'].bind('click', products_link_click)
现在我更大的问题是 register_link
从一开始就不在页面中。更确切地说,register_link
只会在 login_link
link 被点击后加载到 DOM 中,之后寄存器 link 什么都不做,因为事件无法从一开始就绑定它。
现在我知道我可以通过在该页面中再次导入它来轻松绕过它,但我想避免冗余导入,我不太确定具体如何去做。
编辑: 或者在 brython 中有没有办法等待 DOM 完全加载?
这不是常识不能为你工作的 - Brython 在这方面与 Javascript 一样:任何你想要更改的 DOM 元素都需要在你尝试之前存在到 modify/bind 它。
几十年来,"usual" 在 Javascript 中实现这一点的方法一直是将绑定放在一个函数中,然后在页面底部或 body
上调用它标记 onload
事件,在加载其他所有内容之后。 "Modern" Javascript 使用 jQuery 或其他框架及其 ready()
方法对 "solves" 进行编码。
你必须在那里做同样的事情 - 计时器可能会工作,但有风险。当然,触发一个或多个其他函数后才存在的元素应该在各自的函数中处理:
def account_click(ev):
get_data("/account", qs)
document['register_link'].bind('click', register_link_click)
如您所见,account_click
是这样写的:
def account_click(ev):
get_data("/account", qs)
document['register_link'].active = True
document['register_link'].bind('click', register_link_click)
不起作用,因为程序不会等待 get_data
完成后再执行接下来的两行。
一个解决方案是为这种情况编写特定版本的 get_data
和 on_get_complete
(我假设 "register_link" 按钮在页面中,但最初是禁用的):
def complete_register(req):
"""Called when the Ajax request after "login_link" is complete."""
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
# enable "register link" button and add binding
document['register_link'].disabled = False
document['register_link'].bind('click', register_link_click)
else:
document["main_area"].html = "error " + req.text
def get_data_and_register(url, qs):
req = ajax.ajax()
req.bind('complete', complete_register)
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def account_click(ev):
get_data_and_register("/account", qs)
另一种选择是保留通用函数 get_data
和 on_get_complete
,并添加一个可选参数 callback:
def get_data(url, qs, callback=None):
req = ajax.ajax()
req.bind('complete', lambda req:on_get_complete(req, callback))
# Bind the complete State to the on_get_complete function
req.open('GET', url+'?'+qs, True)
req.set_header('content-type', 'application/x-www-form-urlencoded')
req.send()
def on_get_complete(req, callback=None):
if req.status == 200 or req.status == 0:
# Take our response and inject it into the html div with id='main'
document["main_area"].html = req.text
if callback is not None:
callback(req)
else:
document["main_area"].html = "error " + req.text