取消订阅按钮后表单的 EventListener 不起作用

Posted

技术标签:

【中文标题】取消订阅按钮后表单的 EventListener 不起作用【英文标题】:EventListener for form is not working after unsubscribe button 【发布时间】:2022-01-11 15:05:05 【问题描述】:

我有一个小问题。Usign vanilla js 我为电子邮件输入创建了一个表单,在将验证函数发送到 localStorage 并更改按钮状态之后;我为取消订阅电子邮件做了一个事件监听器,它从 localStorage 中删除了电子邮件,但我不能在取消订阅后再次订阅,我只能在刷新页面后才能订阅。 一些截图了解更多细节: 我输入了一个有效的电子邮件:

点击订阅:

点击退订而不刷新页面:

在这种状态下,我无法再次订阅另一封电子邮件,它仅在刷新后才有效,但我需要在不刷新的情况下执行此操作。我该怎么办? 创建此表单的部分是动态创建的。 代码: 订阅函数:

import  validateEmail  from './email-validator.js'

export const subscribe = () => 
  const subscribeBtn = document.getElementById('subscribeButton')
  subscribeBtn.setAttribute('value', 'Unsubscribe')
  document.getElementById('emailForm').style.display = 'none'
  localStorage.setItem('isSubscribed', 'true')


export const unsubscribe = () => 
  const subscribeBtn = document.getElementById('subscribeButton')
  subscribeBtn.setAttribute('value', 'Subscribe')
  document.getElementById('emailForm').style.display = 'block'
  localStorage.setItem('isSubscribed', 'false')


export const subscribeEmail = (email) => 
  const isValidEmail = validateEmail(email)
  if (isValidEmail === true) 
    subscribe()
    document.querySelector('form').addEventListener('click', function (e) 
      e.preventDefault()
      unsubscribe()
      localStorage.removeItem('Email')
    )
   else if (isValidEmail === false) 
    unsubscribe()
  

验证函数:

    const VALID_EMAIL_ENDINGS = ['gmail.com', 'outlook.com', 'yandex.ru']

export const validateEmail = (email) => VALID_EMAIL_ENDINGS.some(v => email.includes(v)) ? true : false

export  VALID_EMAIL_ENDINGS as validEnding 

还有部分创建功能:

import  subscribe, unsubscribe, subscribeEmail  from './subscribe.js'

const addSection = () => 
  const sectionFour = createElement('sectionFour', 'section', 'app-section app-section--image-program', 'fourth-section')
  const sectionParent = getElbyID('sectionParent', 'third-section')
  const parentSection = sectionParent.parentNode
  parentSection.insertBefore(sectionFour, sectionParent.nextSibling)

  const heading2 = createElement('heading2', 'h2', 'program-title')
  const heading2Text = document.createTextNode('Join Our Program')
  heading2.append(heading2Text)
  const parent = getElbyID('parent', 'fourth-section')

  const heading3 = createElement('heading3', 'h3', 'program-subtitle')
  const heading3Text = document.createTextNode('Sed do eiusmod tempor incididunt')
  heading3.appendChild(heading3Text)
  const linebreak = createElement('linebreak', 'br')
  heading3.appendChild(linebreak)
  const textAfterBreak = document.createTextNode('ut labore et dolore magna aliqua')
  heading3.appendChild(textAfterBreak)

  const form = createElement('submitFieldWrapper', 'form', 'submitFieldWrapper', 'form')
  parent.append(heading2, heading3, form)

  const emailForm = createElement('emailForm', 'div', 'form-wrapper', 'emailForm')

  const inputForm = createElement('inputForm', 'input', 'form-input', 'submit-info')
  setAttributes(inputForm,
    'type', 'text',
    'placeholder', 'Email')
  if (localStorage.getItem('Email') !== null) 
    inputForm.setAttribute('value', localStorage.getItem('Email'))
   else 
    inputForm.setAttribute('placeholder', 'Email')
  

  emailForm.appendChild(inputForm)

  document.querySelector('form').addEventListener('submit', function (e) 
    e.preventDefault()
    console.log(inputForm.value)
    localStorage.setItem('Email', inputForm.value)
    subscribeEmail(inputForm.value)
  )

  const submitForm = createElement('submitForm', 'input', 'app-section__button submit-btn', 'subscribeButton')
  setAttributes(submitForm,
    'type', 'submit',
    'value', 'Subscribe')
  form.append(emailForm, submitForm)

  const isSubscribed = localStorage.getItem('isSubscribed')
  if (isSubscribed === 'true') 
    subscribe()
   else if (isSubscribed === 'false') 
    unsubscribe()
  


const createElement = (elName, htmlEl, elClass, elID) => 
  const elementName = document.createElement(htmlEl)
  elementName.className = elClass
  elementName.id = elID

  return elementName


const getElbyID = (elName, searchedId) => 
  const elementToSearch = document.getElementById(searchedId)

  return elementToSearch


const setAttributes = (elem, ...elemArguments) => 
  for (let i = 0; i < elemArguments.length; i += 2) 
    elem.setAttribute(elemArguments[i], elemArguments[i + 1])
  


export const advancedSection = () => 
  addSection()
  const getHeading = document.getElementById('fourth-section')
  const sectionChildren = getHeading.children
  sectionChildren[0].innerHTML = 'Join Our Advanced Program'
  const getButton = document.getElementById('subscribeButton')
  setAttributes(getButton,
    'type', 'submit',
    'value', 'Subscribe to Advanced Program')
  getButton.className = 'app-section__button submit-btnAdvanced'


export default addSection

我不明白我错在哪里或缺少什么,请帮助。在此先感谢。

【问题讨论】:

你确定这个值是你所期望的const isSubscribed = localStorage.getItem('isSubscribed') if (isSubscribed === 'true') subscribe() else if (isSubscribed === 'false') unsubscribe() 不相关:我认为您不应该使用 localStorage 这样做。如果用户删除了他们的浏览器数据怎么办。他们只是不再能够退订吗?您可能应该向 API 添加一个端点来检查给定的电子邮件是否被订阅。 这段代码用于在页面刷新后保持按钮的状态,如果localStorage中有有效的email,那么按钮应该保持取消订阅状态,如果没有电子邮件,那么按钮应该是订阅状态 是的,这不适用于任何商业项目,这是一项获得有关 localStorage 知识的任务,这就是我应该使用它的原因 【参考方案1】:

当您单击“取消订阅”按钮时,您尚未为“订阅”事件重新分配事件处理程序。

添加

  document.querySelector('form').addEventListener('submit', function (e) 
    e.preventDefault()
    console.log(inputForm.value)
    localStorage.setItem('Email', inputForm.value)
    subscribeEmail(inputForm.value)
  )

到您的 unsubcribe() 函数的末尾。

【讨论】:

我试过了,它不起作用。我做的最有帮助的事情是在 isValidEmail === true 时从 subscribeEmail 中删除 preventDefault,并放置一个 stopPropagation 代替,它是这样工作的 或者使用once参数:developer.mozilla.org/en-US/docs/Web/API/EventTarget/…。无论如何,我很高兴你能成功!【参考方案2】:

所以,问题出在 subscribeEmail 函数中,在 e.preventDefault(),idk 它是如何工作的,但我用 stopPropagation 更改了 preventDefault,现在我可以根据需要订阅和取消订阅。 现在的代码如下所示:

    export const subscribeEmail = (email) => 
  const isValidEmail = validateEmail(email)
  if (isValidEmail === true) 
    subscribe()
    document.querySelector('form').addEventListener('click', function (e) 
      unsubscribe()
      localStorage.removeItem('Email')
      e.stopPropagation()
    )
   else if (isValidEmail === false) 
    unsubscribe()
  

【讨论】:

以上是关于取消订阅按钮后表单的 EventListener 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fetch api Javascript 取消订阅电子邮件

使用取消按钮单击提交按钮后阻止表单提交[重复]

从按钮订阅后获取配置文件ID作为响应

捕获 PayPal 订阅取消

java事件机制(订阅/消费模型)/观察者模式 : EventObject,EventListener和Source

特定订阅标识符的 PayPal 取消订阅按钮