【问题标题】:Remove event handler inside function with parameters删除带有参数的函数内的事件处理程序
【发布时间】:2020-05-08 12:09:27
【问题描述】:

我在同一页面上有一些 HTML 表单,在提交前一个表单之后,这些表单一个接一个地依次切换。用户可以在它们之间来回导航,因此我需要在它们被触发后移除提交事件侦听器,以便在需要时重新附加它们。

我目前在“渲染过程”中为它们中的每一个附加提交事件处理程序,在执行如下函数后删除事件处理程序:

form.addEventListener('submit', submitStepOne)

  function submitStepOne(e) {
      e.preventDefault()
      sendData()
      form.removeEventListener('submit', submitStepOne)
  }

多个表单元素的代码相同(submitStepTwosubmitStepThree...)

因为我不想一直重复相同的代码,所以我想创建一个全局的“提交步骤并转到下一个”函数,我认为它可能看起来像这样:

const submitStep = (event, stepNo, trigger) => {
  event.preventDefault()
  toggleStep(stepNo)
  trigger.removeEventListener('submit', submitStep)
}

我想我可以像这样使用.bind() 将事件处理程序附加到提交按钮(来自https://stackoverflow.com/a/23024673/10727821 的提示):

PAGES.step3.functions = function() {
  console.log('step 3')
  let trigger = this.domElement.querySelector('form')
  trigger.addEventListener('submit', submitStep.bind(null, event, 4, trigger))
}

PAGES 是一个对象,其中包含每个步骤的 DOM 元素以及每个页面的相应功能。每次使用toggleStep(step) 切换步骤时,都会调用PAGES.stepX.functions()

但是,我收到了Uncaught TypeError: Cannot read property 'preventDefault' of undefined。我怎样才能重写函数,以便正确地向它传递参数?

感谢任何提示!

【问题讨论】:

    标签: javascript html forms event-handling


    【解决方案1】:

    您在附加submitStep 函数时传递了event 参数,此时为undefined

    您需要重新排列 submitStep 的参数,以便该事件成为最后一个参数,然后使用 .bind() 部分应用 stepNotrigger

    但是您的代码中还有另一个错误。您正在尝试删除其中的 submitStep 的事件侦听器,这在调用 .bind() 后将不起作用,因为 .bind() 返回一个新函数。我会将事件注册分离到一个单独的函数中,该函数将围绕事件处理程序创建一个包装器并将包装器注册为处理程序。然后在执行期间它会调用实际的处理程序并注销自己。

    const addEventListenerOnce = (trigger, eventName, handler) => {
      // Create a function that will be registered as event handler
      const handlerWrapper = (event) => {
        // Call the actual handler
        handler(event);
    
        // Remove the registered wrapper
        trigger.removeEventListener(eventName, handlerWrapper);
      };
    
      // Register the wrapping function as event listener
      trigger.addEventListener(eventName, handlerWrapper);
    };
    
    const submitStep = (stepNo, event) => {
      event.preventDefault();
      toggleStep(stepNo);
    }
    
    PAGES.step3.functions = function() {
      console.log('step 3')
      let trigger = this.domElement.querySelector('form')
      // Only stepNo is applied, event is left
      // Function signature would be then (event) => void
      const submitHandler = submitStep.bind(null, 4);
    
      // Register the submit handler to be called once
      addEventListenerOnce(trigger, 'submit', submitHandler);
    }
    

    【讨论】:

    • 太棒了,非常感谢!也完美地解释了。 ?
    猜你喜欢
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 2012-09-04
    相关资源
    最近更新 更多