0

所以我有以下两难境地:

我正在使用 Brython,一切正常。我有一小段代码为我执行 ajax 请求,我在标题中添加了它以绑定页面中当前元素上的所有内容。

    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,只有在单击链接后才会将其加载到 DOM 中,之后login_link注册链接什么也不做,因为从一开始就无法将事件绑定到它上面。

现在我知道我可以通过在该页面中再次导入它来轻松绕过它,但我想避免多余的导入,而且我不确定如何去做。

编辑:或者在 brython 中有没有办法等待 DOM 完全加载?

4

2 回答 2

1

正如你所注意到的,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在执行接下来的 2 行之前不会等待完成。

一个解决方案是为这种情况编写一个特定版本的get_dataand 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_dataand 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
于 2017-10-11T19:38:17.373 回答
0

这不是常识对你不起作用的——Brython 在这方面的作用与 Javascript 相同:你想要更改的任何 DOM 元素都需要在你尝试修改/绑定它之前存在。

几十年来,在 Javascript 中执行此操作的“通常”方法是将绑定放在一个函数中,然后在加载其他所有内容后,在页面底部或body标记事件上调用它。onload“现代” Javascript 代码通过使用 jQuery 或其他框架及其ready()方法“解决”了这个问题。

你必须在那里做同样的事情 - 计时器可能会工作,但它是有风险的。当然,在一个或多个其他函数被触发之后才存在的元素应该在各自的函数中处理:

def account_click(ev):
    get_data("/account", qs)
    document['register_link'].bind('click', register_link_click)
于 2017-10-11T02:40:42.957 回答