为啥当我更改它的 id 属性时我的按钮没有点击?

Posted

技术标签:

【中文标题】为啥当我更改它的 id 属性时我的按钮没有点击?【英文标题】:Why does my button not click when I change its id attribute?为什么当我更改它的 id 属性时我的按钮没有点击? 【发布时间】:2022-01-18 17:22:25 【问题描述】:

我更改了按钮的属性 id。旧的 id #slide_save_button 是浅蓝色,新的 id #slide_save_button_open 是深蓝色,当它应该改变时会改变。但是当我尝试单击按钮时(通过引用其新 ID #slide_save_button_open),它不会执行 console.log(“clicked”)。为什么?

$("#catName").on("input", function()
  if( $("#catName").val().length > 0 )
    $("#slide_save_button").attr('id', 'slide_save_button_open');
   else 
    $("#slide_save_button_open").attr('id', 'slide_save_button');
  
);



$("#slide_save_button_open").on("click", function()
  console.log("clicked");
);

【问题讨论】:

这只是一个糟糕的策略。 ID 的目的是识别。你为什么要改变它?这样做会破坏所有事件处理程序。改用一个类,或者检查输入的值在点击时(通常是更好的方法)。 因为事件是在代码运行时绑定的。它不会继续寻找匹配的元素。 一个更好的方法是使用css类作为样式,而不是ID。 你仍然需要事件委托。 【参考方案1】:

您的方法失败了,因为代码在那个时刻寻找元素。当它找到它时,它会绑定它。代码不会一直寻找元素。

要按照自己的方式进行,您需要使用事件委托。

$("#catName").on("input", function() 
  if ($("#catName").val().length > 0) 
    $("#slide_save_button").attr('id', 'slide_save_button_open');
   else 
    $("#slide_save_button_open").attr('id', 'slide_save_button');
  
);

$(document).on("click", "#slide_save_button_open", function() 
  console.log("clicked");
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
  <label for="catName">Name:</label>
  <input id="catName" name="catName"/>
  <button type="button" id="slide_save_button" name="slide_save_button">Run</button>
</form>

现在更改 id 并不是最好的解决方案。您可能应该只采用“验证”方法并使用变量来保存状态,或者您可以使用类。

const btn = $("#slide_save_button");

$("#catName").on("input", function() 
  btn.toggleClass("open", $("#catName").val().length > 0);
);

btn.on("click", function() 
  if (btn.hasClass("open")) 
    console.log("clicked");
   else 
    console.log("need to fill in");
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
  <label for="catName">Name:</label>
  <input id="catName" name="catName" />
  <button type="button" id="slide_save_button" name="slide_save_button">Run</button>
</form>

但你可以只使用 html5 验证

const form = $("#myForm");
form.on("submit", function (evt) 
  evt.preventDefault();
  console.log("clicked");
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
  <label for="catName">Name:</label>
  <input id="catName" name="catName" required/>
  <button type="submit" id="slide_save_button" name="slide_save_button">Run</button>
</form>

【讨论】:

【参考方案2】:

$("#slide_save_button_open") 在 DOM 中搜索具有该 ID 现在的元素。然后向它添加一个事件处理程序。

当您稍后更改 ID 时,它不会追溯删除现有的事件处理程序并重新运行原始代码以附加新的。


您可以通过事件委托来实现类似的功能,您可以将事件处理程序绑定到祖先元素并侦听冒泡事件。

$(document).on("click", "#slide_save_button_open", function ()  .... );

您还可以在事件处理程序中测试有关元素的某些内容:

$("#slide_save_button").on("input", function(e) 
    if ( $(e.currentTarget).attr('id') === 'slide_save_button_open') 

也就是说,我建议您测试元素的不同功能,而不是更改 ID。即使处于不同的状态,它仍然是相同的东西。

看看Navigation Menu Button Example。你可以使用aria-expanded="true"

【讨论】:

【参考方案3】:

基于此https://***.com/a/27041899/15924734 无法更改 ID 属性。对于您的需要,您可以使用addClass()removeClass() & toggleClass()

对于动态元素,您也可以使用:

$(document).on("click", "#test-element", function() 
   console.log("clicked");
);

【讨论】:

虽然这是一个很好的建议,但它并没有解决问题(这是关于控制事件处理程序是否根据元素的状态触发)。将更改从 ID 移动到类仍然意味着它不会触发,因为“活动”类在开始时不在元素上。这应该是评论,而不是答案。

以上是关于为啥当我更改它的 id 属性时我的按钮没有点击?的主要内容,如果未能解决你的问题,请参考以下文章

为啥单击按钮时我的选项卡没有变化?

为啥当我按下返回按钮时我的程序崩溃

为啥我调用 .setTitle 时我的 UIButton Text 没有改变? (迅速)

为啥在 Vue 中使用模态时我的 v-if 不触发?

为啥只有当我从 iframe 调用 postMessage() 方法时我的 Angular 属性才会更新

QPrinter 单击按钮时我的程序崩溃为啥?