如何更新 multi-select 并让它实际显示 Chrome 中的新选项
How to update a multi-select and have it actually show the new options in Chrome
我不敢相信,但我发现一些 JS 代码在 IE 11 中完美运行,但在 Chrome(81 版)中不起作用。
我正在从一个多 select 更新另一个,保持选项排序。所以我有一个功能:
/**
* Move the options defined by <sel> from select tag <from> to select tag <to>
* @param from The source SELECT tag jQuery object
* @param to The destination SELECT tag jQuery object
* @param sel Either: "option" for all, or "option:selected"
*/
function moveOpt(from, to, sel) {
var opts = from.children(sel).removeAttr('selected').remove().get();
opts = opts.concat(to.children('option').remove().get());
opts.sort(function (a, b) {
return a.value.localeCompare(b.value);
});
to.append(opts);
/*
// Chrome doesn't re-render the opts until they are selected and then focus is lost ???
window.setTimeout(function() {
to.children('option').attr('selected', 'selected').trigger('click');
from.trigger('focus');
to.children('option').removeAttr('selected');
}, 1);
*/
}
这在 IE 11 中完美运行,但在 chrome 中,选项已移动,但您无法在浏览器中看到它们。它们在那里是因为如果你 "inspect" SELECT 元素,所有的选项标签都在那里,而且 $(to).children().length
显示正确的数字。
如果我取消注释丑陋的 HACK(window.setTimeout()
调用),那么 Chrome 最终会正确显示选项。但必须这样做是疯了。我一定做错了什么。有人知道那是什么东西吗?
Here is a JS fiddle showing the issue - 运行 它在 IE(只读模式)中显示它工作,Chrome 没有。
更新
我尝试将 jQuery 从 1.10.2 升级到 3.5.0,但仍然没有成功。
@ZacharyYaro 也指出它适用于 Chrome 80,但不适用于 81。
改变这个:
to.append(opts);
为此:
var toElm = to.get()[0];
$.each(opts, function(i,v) { toElm.appendChild(v); });
解决了问题。
(重新提交我的评论作为答案,因为它对你有用)
看起来你的 Fiddle 也在 Chrome 80 中工作,然后在 Chrome 81 中中断。看起来 using the built-in selectElement.add
function instead of jQuery (JSFiddle) 在 Chrome 81 中工作,所以看起来 Chrome 81 刚刚破坏了 jQuery 的 $element.append(arrayOfElements)
函数使用的东西。
我不敢相信,但我发现一些 JS 代码在 IE 11 中完美运行,但在 Chrome(81 版)中不起作用。
我正在从一个多 select 更新另一个,保持选项排序。所以我有一个功能:
/**
* Move the options defined by <sel> from select tag <from> to select tag <to>
* @param from The source SELECT tag jQuery object
* @param to The destination SELECT tag jQuery object
* @param sel Either: "option" for all, or "option:selected"
*/
function moveOpt(from, to, sel) {
var opts = from.children(sel).removeAttr('selected').remove().get();
opts = opts.concat(to.children('option').remove().get());
opts.sort(function (a, b) {
return a.value.localeCompare(b.value);
});
to.append(opts);
/*
// Chrome doesn't re-render the opts until they are selected and then focus is lost ???
window.setTimeout(function() {
to.children('option').attr('selected', 'selected').trigger('click');
from.trigger('focus');
to.children('option').removeAttr('selected');
}, 1);
*/
}
这在 IE 11 中完美运行,但在 chrome 中,选项已移动,但您无法在浏览器中看到它们。它们在那里是因为如果你 "inspect" SELECT 元素,所有的选项标签都在那里,而且 $(to).children().length
显示正确的数字。
如果我取消注释丑陋的 HACK(window.setTimeout()
调用),那么 Chrome 最终会正确显示选项。但必须这样做是疯了。我一定做错了什么。有人知道那是什么东西吗?
Here is a JS fiddle showing the issue - 运行 它在 IE(只读模式)中显示它工作,Chrome 没有。
更新
我尝试将 jQuery 从 1.10.2 升级到 3.5.0,但仍然没有成功。
@ZacharyYaro 也指出它适用于 Chrome 80,但不适用于 81。
改变这个:
to.append(opts);
为此:
var toElm = to.get()[0];
$.each(opts, function(i,v) { toElm.appendChild(v); });
解决了问题。
(重新提交我的评论作为答案,因为它对你有用)
看起来你的 Fiddle 也在 Chrome 80 中工作,然后在 Chrome 81 中中断。看起来 using the built-in selectElement.add
function instead of jQuery (JSFiddle) 在 Chrome 81 中工作,所以看起来 Chrome 81 刚刚破坏了 jQuery 的 $element.append(arrayOfElements)
函数使用的东西。