级联下拉菜单 - 如何暂时禁用下拉菜单上的更改事件以操作选项

发布于 2024-11-25 06:44:22 字数 1179 浏览 1 评论 0原文

我在 jquery 中构建了一个级联下拉列表,并根据一些示例进行了修改。我添加了一项功能,让用户“备份”并重新选择较早的下拉列表。这将重新加载下一个下拉列表,并清除并禁用后续下拉列表。

http://jsfiddle.net/goodeye/gA6GZ/

问题是在第一次通过后,选择元素的更改事件是绑定的,因此我认为重新加载新值会导致稍后的更改事件触发。

我分离出了​​ .change() 绑定,而不是链接它。我之前在加载选择选项之前将其链接起来。这在第一次时有帮助,但在随后的几次中却无济于事。

对于这个问题,我专门寻找一个解决这个序列的好方法:

  • 避免change()
  • 更新下拉菜单
  • 设置change()

这个问题: 在 jQuery 中删除事件处理程序的最佳方法? 将 unbind() 作为主要答案,然后是使用 live() 的后续答案。 live() 方法使用了一个让我有点困惑的类,并且没有得到那么多的投票。

重现:
选择步骤1,参见步骤2火。
选择步骤2,参见步骤3火。
再次选择步骤 1,看到步骤 2 启动。
然后麻烦就开始了:
选择步骤 2,看到步骤 3 触发两次。
选择步骤3,看到步骤4触发三次。
再次选择步骤 1,看到步骤 2 触发两次。
等等
甚至变得更糟;我将看到步骤 3 触发五次。

一些细节:

在实际代码中,这些是从 json ajax 调用加载的。我从示例中删除了它,并添加了硬编码选项来模拟它,将其范围仅限于事件问题。

这从服务器端开始,因此第一个下拉列表已经在 html“中”了。接下来的三个是从(模拟的)json 调用加载的。

这些使用类进行标识,因为真实页面具有不止一组这些下拉列表。该代码使用 $(this) 来小心地在选定的一组内工作。

如果只有一个选项,还有一项“自动选择”功能,然后转到下一个选项。这段代码就在那里,但是模拟的示例都有不止一个选项,以避免这个问题的这个问题。

预先感谢您的想法!

I built a cascading dropdown in jquery, modified from a few examples. I added a feature to let the user "back up" and reselect an earlier dropdown. This reloads the next dropdown, and clears and disables the subsequent ones.

http://jsfiddle.net/goodeye/gA6GZ/

The problem is after the first time through, the select elements' change events are bound, so I think reloading new values is causing the later change events to fire.

I separated out the .change() bind, instead of chaining it. I previously had it chained before loading the select options. This helped the first time through, but not subsequent times.

For this problem, I'm specifically looking for a good approach to this sequence:

  • avoid change()
  • update the dropdowns
  • set up change()

This question:
Best way to remove an event handler in jQuery?
has unbind() as the main answer, then a subsequent answer to use live(). The live() approach uses a class which is slightly confusing me, and didn't get as many votes.

To reproduce:
Select step 1, see step 2 fire.
Select step 2, see step 3 fire.
Select step 1 again, see step 2 fire.
then the trouble starts:
Select step 2, see step 3 fire twice.
Select step 3, see step 4 fire three times.
Select step 1 again, see step 2 fire twice.
etc.
It even gets worse; I'll see step 3 fire five times.

Some details:

In the real code, these load from a json ajax call. I removed that from the example, and added hard-coded options to simulate it, scoping this to just the event issue.

This starts out server-side, so the first dropdown is already "in" the html. The next three are loaded from (simulated) json calls.

These use classes for identification, because the real page has more than one set of these dropdowns. The code uses $(this) to be careful to work within the one set that was selected.

There is also a feature to 'auto select' if there's only one option, and move on to the next one. This code is in there, but the simulated examples all have more than one option, to avoid this issue for this question.

Thanks in advance for your ideas!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绿萝 2024-12-02 06:44:22

你可以做的是使用 jQuery 检查元素上所有绑定的更改事件,将它们保存在“离线”数组中,取消绑定它们,做你的事情,然后重新绑定它们。

要检查所有绑定的更改事件,您可以使用:

var changeEvents = $(element).data("events").change;
jQuery.each(changeEvents, function(key, handlerObj) {
    alert(handlerObj.handler) // alerts "function() { alert('changed!') }"
    // also available: handlerObj.type, handlerObj.namespace
})

What you can do is use jQuery to inspect all the bound change events on the element, keep them in an "offline" array, unbind them, do your stuff and them rebind them.

To inspect all bound change events you can use:

var changeEvents = $(element).data("events").change;
jQuery.each(changeEvents, function(key, handlerObj) {
    alert(handlerObj.handler) // alerts "function() { alert('changed!') }"
    // also available: handlerObj.type, handlerObj.namespace
})
已下线请稍等 2024-12-02 06:44:22

好吧,我没时间了,必须解决它。只需设置一次绑定即可 - 仅此而已。所以这解决了问题,并且不需要取消绑定/重新绑定,或者在这种情况下使用 live() 。

预先执行以下代码。它绑定下拉菜单一次,并禁用第二个、第三个、第四个,直到从调用第一个下拉菜单开始级联。因此绑定完成一次,然后切换禁用真/假。

$('.ddStep1').change(getStep2);
$('.ddStep2').change(getStep3).attr('disabled', true);
$('.ddStep3').change(getStep4).attr('disabled', true);
$('.ddStep4').attr('disabled', true);

(在此应用程序中,最后一个下拉列表没有更改事件;选择第四个下拉列表后有一个单独的提交按钮。)

问题是创建绑定的多次调用 - 这是一次性的事情,因此调用它不止一次在更改事件上附加多个调用。

添加和删​​除选择选项不会调用更改事件。

回答关于暂时禁用事件的原始问题(尽管不是我的问题的解决方案),我确实从这个答案中理解了使用 live() ,并认为这将是正确的方法:
在 jQuery 中删除事件处理程序的最佳方法?
使用名称空间对该问题的另一个答案看起来也不错。

Well, I ran out of time and had to solve it. It was simply to set up the binding once - that's all there was to it. So this solves the problem, and didn't need to unbind/rebind, or use live() in this case.

Do the following code once up front. It binds the dropdowns once, and disables the 2nd, 3rd, 4th until the cascading starts from calling the first one. So the binding is done once, then disabled true/false is toggled.

$('.ddStep1').change(getStep2);
$('.ddStep2').change(getStep3).attr('disabled', true);
$('.ddStep3').change(getStep4).attr('disabled', true);
$('.ddStep4').attr('disabled', true);

(In this application, the last dropdown doesn't have a change event; there's a separate submit button after the 4th is selected.)

The problem was the multiple calls to create the binding - this is a one-time thing, so calling it more than once was attaching multiple calls on the change event.

Adding and removing the select options wasn't calling the change event.

Answering the original question about temporarily disabling the event (albeit not the solution for my problem), I did get to understand using live() from this answer, and think that would be the way to go:
Best way to remove an event handler in jQuery?
The other answer to that question using namespaces looks decent too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文