eventListener 在刷新 JS 之前多次触发
Posted
技术标签:
【中文标题】eventListener 在刷新 JS 之前多次触发【英文标题】:eventListener is firing multiple times before the refresh JS 【发布时间】:2022-01-11 07:03:44 【问题描述】:我正在为电子邮件表单制作一个简单的提交按钮,当单击提交按钮并且电子邮件有效时,它将按钮的状态从“订阅”更改为取消订阅并隐藏表单。到这里一切都很好,但问题是当我单击提交按钮时,它会执行我需要的操作,但是在我输入有效的电子邮件并更改按钮的状态后,相反的操作没有完成,它继续发送电子邮件到本地存储,而不是删除它。 在这里我添加了一个无效的电子邮件: 在控制台日志中我有这封电子邮件。 在这里我添加了一个有效的电子邮件而不刷新页面:
现在,当我单击取消订阅时,它应该从 localStorage 中删除电子邮件并返回表单和按钮的状态,但相反,它会执行提交操作..:
我该怎么办?我是 JS 新手,在这里我只使用 vanilla js。
使用提交按钮的代码:
document.querySelector('form').addEventListener('submit', function (e)
e.preventDefault()
console.log(inputForm.value)
localStorage.setItem('Email', inputForm.value)
subscribeEmail(inputForm.value);
)
下面的代码用于在刷新页面时保持按钮的状态:
const isSubscribed = localStorage.getItem('isSubscribed')
if (isSubscribed === 'true')
subscribe()
// document.querySelector('form').addEventListener('click', function (e)
// e.preventDefault()
// unsubscribe()
// localStorage.removeItem('Email')
// )
else
unsubscribe()
下面是改变按钮状态的代码: 编辑:我修改了下面的代码,现在我可以在不刷新页面的情况下取消订阅,现在的问题是我无法提交另一个值进行验证并在 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) =>
if (validateEmail(email) == true)
subscribe();
document.querySelector('form').addEventListener('click', function (e)
e.preventDefault()
unsubscribe()
localStorage.removeItem('Email')
)
else if (validateEmail == false)
unsubscribe();
;
这里是验证函数:
const VALID_EMAIL_ENDINGS = ['gmail.com', 'outlook.com', 'yandex.ru']
export const validateEmail = (email) =>
if (VALID_EMAIL_ENDINGS.some(v => email.includes(v)))
return true
else
return false
export VALID_EMAIL_ENDINGS as validEnding
我不明白出了什么问题,或者这通常会发生..它让我有机会在刷新页面后“取消订阅”,但我想订阅和取消订阅多次而不需要刷新。
我应该提一下,创建按钮的部分显示为usign window.onload,因此它是动态创建的。
编辑:
全段创建代码:
import subscribe, unsubscribe from './subscribe.js'
import 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()
// document.querySelector('form').addEventListener('click', function (e)
// e.preventDefault()
// unsubscribe()
// localStorage.removeItem('Email')
// )
else
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
还有 main.js
import addSection, advancedSection from './join-us-section.js'
class SectionCreator
constructor (type)
this.type = type
create (type)
if (type === 'standard')
addSection()
else if (type === 'advanced')
advancedSection()
return type
remove ()
const sectionToRemove = document.getElementById('fourth-section')
sectionToRemove.remove()
window.onload = new SectionCreator().create('standard')
我设法在不刷新页面的情况下取消订阅,但现在的问题是,如果不刷新我就无法输入另一个输入.. 这就是我在不刷新的情况下取消订阅的方式:
export const subscribeEmail = (email) =>
if (validateEmail(email) == true)
subscribe();
document.querySelector('form').addEventListener('click', function (e)
e.preventDefault()
unsubscribe()
localStorage.removeItem('Email')
)
else if (validateEmail == false)
unsubscribe();
;
这个事件监听器在 isSubscribed 函数中,但我把它移到了 subscribeEmail,它在那里检查验证。上面的代码最后可能不同,因为我重命名了变量,从 unsubscribeToggle 到 isSubscribed,从 getUnsubscribe 到 subscribe 和从 getSubscribe退订
【问题讨论】:
【参考方案1】:我设法在不刷新的情况下取消订阅:
export const subscribeEmail = (email) =>
if (validateEmail(email) == true)
subscribe();
document.querySelector('form').addEventListener('click', function (e)
e.preventDefault()
unsubscribe()
localStorage.removeItem('Email')
)
else if (validateEmail == false)
unsubscribe();
;
我只是玩了一些功能,并把它们放在了位置。我修复了我不能订阅和取消订阅很多次的问题。 我应该只删除函数中的 preventDefault 并使用 stopPropagation 进行更改:
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()
【讨论】:
【参考方案2】:如果不查看所有代码,很难在此处修改所有内容,而且 localStoage 在 sn-ps 中不起作用。看看这个例子是否有帮助。它只使用一点代码来管理订阅与取消订阅功能,而无需刷新页面。
// init code
let hasSubscribed = false
let userEmail = ''
let subBtnEl, inputEl, resultEl
window.addEventListener('DOMContentLoaded', () =>
// userEmail = localStorage.getItem('email') || '';;
subBtnEl = document.querySelector('button#sub');
inputEl = document.querySelector('input[name=email]');
resultEl = document.querySelector('#result');
subBtnEl.addEventListener('click', e =>
resultEl.innerText = "";
doButton()
)
)
function isValidEmail(email)
return true;
function doButton()
// check localStorage
hasSubscribed = userEmail.trim() !== '';
if (!hasSubscribed)
if (!isValidEmail(inputEl.value))
resultEl.innerText = "Invalid Email";
return
userEmail = inputEl.value;
inputEl.setAttribute('hidden', true);;
subBtnEl.innerText = "Unsubscribe";
resultEl.innerText = "You've been subscribed!";
// localStorage.setItem('email', subBtnEl.value.trim());
else
// localStorage.setItem('email', '');
userEmail = '';
inputEl.removeAttribute('hidden');;
resultEl.innerText = "You've been unsubscribed";
subBtnEl.innerText = "Subscribe";
<div id='result'></div>
<input type='text' name='email' />
<button id='sub'>Subscribe</button>
【讨论】:
我将 unsubscribeToggle 中的事件监听器添加到 getUnsubscribe 函数中,这样我就可以在不刷新页面的情况下取消订阅。但取消订阅后我无法提交另一个值。如果更容易理解,我添加了创建该部分的整个代码。以上是关于eventListener 在刷新 JS 之前多次触发的主要内容,如果未能解决你的问题,请参考以下文章