使用自定义DOM功能时,表格第二次使用preventDefault重新加载页面

时间:2018-05-20 15:25:40

标签: javascript coffeescript

我有一个登录表单,在提交时会调用此函数

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时添加“加载微调器”,然后将其删除。这在第一次提交表单时工作正常,因为我正在使用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

1 个答案:

答案 0 :(得分:1)

问题在于如何将事件侦听器附加到元素。 您尝试做的事情并不适用于纯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