当通过JS更改值时,jQuery Chosen未触发onchange事件

9

JSFiddle

我在这个示例中设置了一个带有 3 个选项(1 个空白)的 select。当我手动从 foo 切换到 bar 时,change 监听器会正常触发。

现在,如果我使用此处发布的代码通过 JS 重置 select,则新选择的空白选项不会触发 change 事件,而且如果我选择之前单击 reset 按钮所选中的选项,则 onchange 事件也不会触发。

我确信上述函数正在更改 select 的值,可以在此示例中看到,但是 selectonchange 事件根本不会触发。

我还尝试过 onchangeonclickoninput 事件,但都无济于事。现在我想知道是否应该使用 MutationObserver 或从 DOM 中删除呈现的 chosen 元素并创建另一个元素,但我可能想太多了。感谢任何帮助。

还有:

这个答案对我很有帮助:jQuery Chosen reset

这个答案没有帮助:how to fire onchange event in chosen prototype javascript select box?

如果 jsfiddle.net 被关闭,以下是代码供参考:

HTML

<div id="wrapper">
    <select id="chosen">
        <option value="!!EMPTY VALUE!!"></option>
        <option value="foo">foo</option>
        <option value="bar">bar</option>
    </select>
</div>
<br>
<button id="reset">Reset</button>

JS

$(function() {
    $('#chosen').chosen();

    $('#wrapper').on('change', '#chosen', function() {
        console.log('onchange: ' + this.value);
    });

    $('#reset').click(function() {
        $("#chosen").val('').trigger("liszt:updated"); //doesn't work
        //$("#chosen").prop('selectedIndex', 0).trigger("liszt:updated"); //doesn't work either
        console.log('reset: ' + $('option:selected').val());
    });
});

ASP.Net Webforms:当我的应用程序似乎出现了这个问题时,我遇到了这个问题,但事实证明这是由于ASP WebForm Validators引起的Javascript错误。请参见此jQuery-UI ticket - sparebytes
2个回答

9

在您使用 $(selector).trigger("change") 更改值后,您需要触发更改。

$('#reset').click(function() {
        $("#chosen").val('').trigger("change"); //doesn't work
        //$("#chosen").prop('selectedIndex', 0).trigger("liszt:updated");
        console.log('reset: ' + $('option:selected').val());
    });

还有 foo -> reset -> foo 这种情况不会触发最后一个 foo,但我现在应该能自己解决了。 - Fabrício Matté
@FabrícioMatté,.chosen 函数是什么? - Adam Merrifield
.chosen 是 Chosen 插件本身,它将 select 转换为 chosen select。不过像往常一样,这可能是他们代码中的一个 bug。 =] - Fabrício Matté
1
我已经解决了,虽然有点丑陋但是对于未来可能遇到相同问题的人来说:$('#chosen_chzn').remove(); $('#chosen').val('').change().removeClass('chzn-done').chosen(); Fiddle - Fabrício Matté
3
#chosen是上述代码中select的ID,因此更合适的解决方法是:var selId = 'chosen'; $('#'+selId+'_chzn').remove(); $('#'+selId).val('').change().removeClass('chzn-done').chosen();- Fiddle - 最后注意,Chosen插件在添加新功能方面是我见过最糟糕的。 - Fabrício Matté

5

我从Fabrício Matté的评论中复制了一个对我有用的答案,这样其他人就不会像我一样在一开始错过了解决方案。

$('#chosen_chzn').remove();
$('#chosen').val('').change().removeClass('chzn-done').chosen();

点击这里在他的Fiddle上查看

我最初尝试继续使用.trigger('liszt:updated')调用而不是.change(),但那并没有起作用。也没有看到.removeClass('chzn-done')背后的原因,但这也是必不可少的,否则您的选择框将会消失。


3
实际上,我认为我已经找到了另一个“更好”的解决方案。不太确定。我想我刚刚升级到了 Select 2,它只需在原始输入上调用 .change() 即可触发 change 事件。 - Fabrício Matté
1
对于那些被困在Chosen上的人,给一个加分。我不完全记得为什么要删除 chzn-done 类,但我非常确定这是因为 chzn-done 对你调用了 . chosen()select 元素应用了 display:none 并且对带有该类的元素调用 .chosen() 将无法工作。 - Fabrício Matté
1
我认为如果您不删除chzn-done,则调用chosen()将无效 - 它认为自己已经设置完毕。这是一种较简单的保护措施。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接