使用自定义 DOM 函数时,表单使用 preventDefault 第二次重新加载页面
Form reloads page 2nd time with preventDefault when using custom DOM function
我有一个登录表单,提交后会调用此函数
login = (that) ->
header =
"X-CSRFToken": window.csrftoken
$('body').toggleDOM('.loading', true)
fermata.json("/login").post(header, that, (err, data) ->
$('body').toggleDOM('.loading', false)
if !data.success
htAlert.error 'Incorrect username and/or password.'
)
这将在调用 API 时添加一个 "loading spinner",然后将其删除。这在您第一次提交表单时工作正常,因为我使用 preventDefault
所以页面不会重新加载。但是在第二次尝试时,页面会重新加载,我不知道为什么会这样。
我的 DOM 函数向主体添加元素:
$.fn.toggleDOM = (domName, b) ->
dom = domName[domName.search(/([\.\#])/)]
newDom = domName.substring(1)
if dom == '#'
if b
document.body.innerHTML += '<div id="' + newDom + '"></div>'
else
document.getElementById(newDom).remove()
else
if b
document.body.innerHTML += '<div class="' + newDom + '"></div>'
else
document.getElementsByClassName(newDom)[0].remove()
表单提交事件:
$ ->
trigger = document.querySelectorAll("[data-trigger]")
trigger.forEach((i) ->
i.addEventListener "submit", (e) ->
e.preventDefault()
# We have to pass the event instead of the element.
switch i.attributes["data-trigger"].nodeValue
when "[form/login]" then login(e)
HTML:
<form data-trigger="[form/login]" class="login">
<input type="hidden" class="uuid hidden">
<input placeholder="Username" class="username">
<input placeholder="Password" type="password" class="password">
<button type="submit">Login</button>
</form>
我需要知道为什么它会在第二次尝试时重新加载页面。如果我删除 $('body').toggleDOM('.loading', true)
它不会像那样运行并按预期工作。
此外,我不使用jQuery,我使用这个小库:https://github.com/finom/balalaika
问题在于如何将事件侦听器附加到元素。
您尝试做的事情在 JavaScript.
中不起作用
你需要利用的是事件委托;它不会改变太多代码,但会改变它的工作方式。
通过删除 for 循环并将处理程序附加到 document
,您将得到想要的东西。
document.addEventListener "submit", (e) ->
e.preventDefault();
switch e.target.attributes["data-trigger"].nodeValue
when "[form/login]" then login(e)
有一篇很棒的文章涵盖了 the how and why
我有一个登录表单,提交后会调用此函数
login = (that) ->
header =
"X-CSRFToken": window.csrftoken
$('body').toggleDOM('.loading', true)
fermata.json("/login").post(header, that, (err, data) ->
$('body').toggleDOM('.loading', false)
if !data.success
htAlert.error 'Incorrect username and/or password.'
)
这将在调用 API 时添加一个 "loading spinner",然后将其删除。这在您第一次提交表单时工作正常,因为我使用 preventDefault
所以页面不会重新加载。但是在第二次尝试时,页面会重新加载,我不知道为什么会这样。
我的 DOM 函数向主体添加元素:
$.fn.toggleDOM = (domName, b) ->
dom = domName[domName.search(/([\.\#])/)]
newDom = domName.substring(1)
if dom == '#'
if b
document.body.innerHTML += '<div id="' + newDom + '"></div>'
else
document.getElementById(newDom).remove()
else
if b
document.body.innerHTML += '<div class="' + newDom + '"></div>'
else
document.getElementsByClassName(newDom)[0].remove()
表单提交事件:
$ ->
trigger = document.querySelectorAll("[data-trigger]")
trigger.forEach((i) ->
i.addEventListener "submit", (e) ->
e.preventDefault()
# We have to pass the event instead of the element.
switch i.attributes["data-trigger"].nodeValue
when "[form/login]" then login(e)
HTML:
<form data-trigger="[form/login]" class="login">
<input type="hidden" class="uuid hidden">
<input placeholder="Username" class="username">
<input placeholder="Password" type="password" class="password">
<button type="submit">Login</button>
</form>
我需要知道为什么它会在第二次尝试时重新加载页面。如果我删除 $('body').toggleDOM('.loading', true)
它不会像那样运行并按预期工作。
此外,我不使用jQuery,我使用这个小库:https://github.com/finom/balalaika
问题在于如何将事件侦听器附加到元素。 您尝试做的事情在 JavaScript.
中不起作用你需要利用的是事件委托;它不会改变太多代码,但会改变它的工作方式。
通过删除 for 循环并将处理程序附加到 document
,您将得到想要的东西。
document.addEventListener "submit", (e) ->
e.preventDefault();
switch e.target.attributes["data-trigger"].nodeValue
when "[form/login]" then login(e)
有一篇很棒的文章涵盖了 the how and why