【问题标题】:What is the returned value of a clicked <button>?单击的 <button> 的返回值是多少?
【发布时间】:2021-01-28 13:45:59
【问题描述】:

我想得到一个点击按钮的返回值,然后用它来做一个if 语句。我在这里读到的关于人们尝试这样做的所有答案要么是非常古老的使用不再起作用的旧脚本,要么是不同的情况。

function remove() {
  if (document.getElementById("removing").value == true) {

    document.getElementById("test").style.backgroundColor = "red";
  }
}
<div id="test">test</div>
<button id="removing" onclick="remove()">Remove a word</button>

我尝试过使用value 和onclick 属性,但是当单击按钮时,它们都不等于true。

我尝试使用alert 显示value,但它什么也没显示。

点击按钮是否真的返回一个值,如果是,它是什么?

【问题讨论】:

  • 不,单击按钮不会返回值。通常,事件不会“返回”任何值。它们只是发生,您可以注册事件处理程序以在它们发生时执行。 remove 被执行的事实意味着该按钮被点击了。
  • 我明白了。那么,我该怎么做呢?如何在 if 语句中使用已执行的事件?
  • 我不明白您为什么需要if 声明?您想知道按钮在哪里被点击?请提供更多上下文。在您的示例中,remove 已被调用这一事实意味着该按钮已被单击。
  • @PeterSeliger:可能。但它只能帮助OP澄清:)
  • 对不起,我还没有回复。我在这里阅读了所有答案,但我现在正试图吸收和理解大量信息。我现在正在测试和试验一大堆东西。鉴于我对 JS 很陌生,我一直看到的一些东西对我来说没有意义,我正在努力理解它,并提出一些关键问题,以便我可以在有的时候问你们机会。请给我一些时间,然后我才能以更恰当的方式提出我的问题。

标签: javascript dom events event-handling


【解决方案1】:

DOM Events 由 EventListener 的 callback function 处理。

因此,这样的处理函数,如果由事件触发并由事件侦听器的 handleEvent 方法转发,将始终使用事件对象作为此函数的单个参数来调用。

与此事件相关的所有信息均由事件本身携带。它的属性可以读取,有些甚至可以写入/更改。

从提供的示例中可以明显看出,OP 希望确保事件处理程序仅由特定的 html 元素触发。因此,任何有效的方法只需要查看事件的currentTarget 属性...

// the way the OP might want to handle the problem.
function handleRemoveWord(evt) {
  const elmNode = evt.currentTarget;

  // make sure the handler was
  // triggered by the intended element ...
  // ... here by comparing node properties.
  if (
    (elmNode.tagName.toUpperCase() === 'BUTTON')
    && (elmNode.id === 'remove')
  ) {
    document
      .getElementById('test')
      .style.backgroundColor = 'red';
  }
}

// another way the OP might want to handle the problem.
function handleRemoveAnotherWord(evt) {

  // `this` referres to the element which got
  // bound to the handler via `addEventListener`.
  const targetNode = this;

  // make sure the handler was
  // triggered by the intended element ...
  // ... here by comparing node references.
  if (targetNode === evt.currentTarget) {
    document
      .getElementById('test')
      .style.backgroundColor = 'cyan';
  }
}

// an alternative way of solving the problem
// of always being assured about the correct
// element having triggering the event handling.
function handleRestoreWordWithBoundContext(evt) {
  const context = this;
  const { elmTest, elmRestore } = context;

  // make sure the handler was
  // triggered by the intended element ...
  // ... here by comparing node references.
  if (elmRestore === evt.currentTarget) {

    elmTest.style.backgroundColor = '';
  }
}


function initialize() {
  // the way(s) the OP might want to handle the problem.
  document
    .getElementById('remove')
    .addEventListener('click', handleRemoveWord);

  document
    .querySelector('#removeAnother')
    .addEventListener('click', handleRemoveAnotherWord);

  // an alternative way of soving the problem
  // of always being assured about the correct
  // element having triggering the event handling.
  const elmTest = document.querySelector('#test');
  const elmRestore = document.querySelector('#restore');

  elmRestore.addEventListener(
    'click',
    handleRestoreWordWithBoundContext.bind({
      elmTest, 
      elmRestore,
    })
  );
}
initialize();
<div id="test">test</div>

<button id="remove">Remove a word</button>
<button id="removeAnother">Remove another word</button>
<button id="restore">Restore a word</button>

您可能已经注意到,该示例具有第三个按钮,该按钮具有另一种实现事件处理程序的方式。此附加处理程序假定其this 上下文来携带附加信息。这可以通过在此处理程序函数上调用bind 并准确提供希望作为事件处理程序this 上下文出现的信息来实现。每次调用此函数特定方法时,它都会创建另一个函数,该函数确实可以通过 this 关键字访问绑定信息。

【讨论】:

    【解决方案2】:

    只需将按钮的背景颜色更改为:

    function remove() {
      document.getElementById("test").style.backgroundColor = "red";
    }
    <div id="test">test</div>
    <button id="removing" onclick="remove()">Remove a word</button>

    【讨论】:

    • 我认为 OP 试图解决的不是上面显示的基本类型的事件处理。 OP 正在寻找一种方法来确保某个元素是事件的触发器或事件的当前目标。
    【解决方案3】:

    调度 Javascript 事件处理程序总是返回 true,即使它返回 false,我们都知道这是用于防止事件的默认行为。我们通常不使用事件处理程序的返回值,甚至不返回任何东西。

    在您的情况下,我认为您正在尝试访问 currentTarget 元素的值(在您的情况下是“删除”按钮)。为此,您可以使用事件对象,该对象作为参数传递给您的事件处理程序。

    event.currentTarget 是一种引用正在调度(触发)事件的元素的方式。就像在事件处理程序中使用“this”一样,除了它也适用于箭头函数。

    所以做这样的事情:

    function remove(event) {
      let button = event.currentTarget;
      if (buttton.value) {
       document.getElementById("test").style.backgroundColor ="red";
      }
    }
    

    在 HTML 中,

    <div id="test">test</div>
    <button id="removing" onclick="remove(event)">Remove a word</button>
    

    注意我使用了 remove(event)。

    根据以下评论编辑: 使用 onclick 将要求您创建一个全局“删除”功能。 如果你这样做,'...onclick="remove(event)" 它基本上做的是创建下面的函数,基本上是一个包装器:

    // In the global scope
    [reference element].onclick = ()  => {
      remove(event);
    }
    

    所以你必须有一个全局的“删除”功能。所以这在模块中不起作用,因为每个模块都有自己的顶级范围。如果您打算从事复杂的项目,您将不得不使用模块。

    注意在 html 中使用内联 'onclick' 属性对来自下面评论的大量请求有以下缺点:

    -关注点分离:您通常不希望将您的 UI 逻辑(单击按钮时发生的事情)与演示相混淆。您需要在内容、样式和脚本之间进行明确划分。

    -使用 onclick 只能分配一个处理程序。

    -如果内联指定事件,则将 JS 指定为字符串(属性值始终为字符串)并在事件触发时进行评估。(内部构建额外的包装代码)。

    -正如我之前提到的,您必须引用命名函数。这并不理想,并且对需要全局的函数有影响,当您使用模块时,这会真正让您反胃。

    简而言之,通过专用的 addEventListener API 集中处理事件。

    【讨论】:

    • 请不要使用'event'作为全局out of the blue变量,因为它是通过给定的示例内联样式实践的...&lt;button ... onclick="remove(event)"&gt;...什么真正需要的是通过[buttonReference].addEventListener('click', remove) 正确初始化/注册remove 事件处理程序。请相应地更改您的代码,甚至尝试使其成为可执行的 sn-p。提前致谢。
    • @PeterSeliger 你觉得上面的编辑怎么样。我是编程新手,通常可以真正使用意见。提前致谢。
    • 但事件并非总是这样可用。这不像我们需要从某个地方导入它是吗?还是我错过了什么?因为你太棒了。
    • 使用内联事件处理和全局 event 对象被认为是有害的,因此是不好的做法。
    • @Peter Seliger 解释为什么它被认为是有害的。
    猜你喜欢
    • 1970-01-01
    • 2017-01-06
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多