我有这种情况。一个带有knockoutjs的jquery自动完成功能,除IE8外,适用于所有浏览器。当我们在自动完成列表中选择一个项目时,在我们单击(选择)一个列表项后,正常行为将关闭该列表。
但是,在IE8中,列表仍然打开。我已经做了几乎所有事情来破解这个bug,但没有成功。我们的客户是在所有PC上都安装了IE8的公司,我们需要调整此功能以适用于IE8。
下面,我提供了一些代码来说明问题:
HTML:
<div class="lado-a-lado-linear" data-bind="visible: parametros().usaCentroDeCusto || plano().centroDeCusto()">
<label>Centro de Custo <span class="requerido" data-bind="visible: parametros().centroDeCustoObrigatorio">*</span></label>
<input type="text" data-bind="value: (plano().centroDeCusto() || {}).nome, autocomplete: { source: onRequestCentroDeCusto, minLength: 0, select: onSelectCentroDeCusto, change: onChangeCentroDeCusto, scroll: onScrollCentroDeCusto, requestOnFocus: true }, validationElement: plano().centroDeCusto, enable: editaDadosPlano" />
</div>
自动完成的敲除扩展程序:
ko.bindingHandlers.autocomplete = {
init: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
$(element).autocomplete(options);
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).autocomplete("destroy");
});
if (options.requestOnFocus)
$(element).focus(function(){
if ($(element).autocomplete("widget").is(":visible"))
return;
$(element).data("uiAutocomplete").search($(this).val());
});
if (options.multipleSelection) {
$(element).parent().click(function () { Expense.mainViewModel.resizeAutocomplete($(element).parent()); });
$(element).blur(function () { $(element).width(0); });
}
if (options.scroll)
$(element).autocomplete("widget").scroll(function () {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight)
options.scroll(element);
});
$(element).bind('keydown', function (event) {
var viewModel = Expense.mainViewModel || Expense.loginViewModel;
return viewModel.onKeyDownAutocomplete(event, options.change);
});
},
update: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
$(element).autocomplete("option", options);
}
};
Knockout viewmodel:
self.centrosDeCusto = []
self.onRequestCentroDeCusto = function (request, response) {
var append = request.term.indexOf('{append}') > -1;
var skip = append ? '&$skip=' + self.centrosDeCusto.length.toString() : '';
var terms = '?$top=30&select=id,nome&nome=' + request.term.replace('{append}', '') + skip;
var url = self.resolveUrl('usuarios/' + self.plano().favorecido().id + '/centrosdecusto/' + terms);
self.ajaxRequest('GET', url)
.done(function (data) {
if (append)
self.centrosDeCusto = self.centrosDeCusto.concat(data);
else
self.centrosDeCusto = data;
response($.map(self.centrosDeCusto, function (item) {
return {
label: item.nome,
value: item.nome,
data: item
}
}));
});
};
self.onScrollCentroDeCusto = function (element) {
if (self.centrosDeCusto.length < 30 || self.centrosDeCusto.length % 30 == 0)
$(element).autocomplete("search", $(element).val() + '{append}');
};
self.onSelectCentroDeCusto = function (event, ui) {
self.plano().centroDeCusto(ui.item.data);
};
self.onChangeCentroDeCusto = function (event, ui) {
ui = ui || {};
if ($(event.currentTarget).val() == '')
self.plano().centroDeCusto(null);
else if (!ui.item && self.centrosDeCusto.length == 1)
self.plano().centroDeCusto(self.centrosDeCusto[0]);
else if (self.plano().centroDeCusto() && self.plano().centroDeCusto().nome == $(event.currentTarget).val()) {
}
else if (!ui.item && $(event.currentTarget).val() != '') {
self.plano().centroDeCusto(null);
setTimeout(function () { alert("É necessário selecionar um Centro de Custo da lista"); }, 0);
$(event.currentTarget).focus();
return false;
}
return true;
};
所以,我需要在所有浏览器中实现相同的行为,即:在我们编写搜索词之后,会出现自动完成火灾和带有项目的列表。然后我们选择其中一个项目,列表消失/关闭。
仅在IE8中,此列表继续显示,显示我选择的所选项目,就在输入字段下方。此列表仅在我模糊字段时关闭。但是,每次单击输入字段时,列表都会再次显示。
我不知道问题是关于knockoutjs还是jquery ui,或两者兼而有之。
我已尝试使用以下版本但未成功。它可能是某些版本的组合?!?!
祝你好运, 马塞洛。
答案 0 :(得分:0)
对于需要解决与此类似的错误的每个人,我已经解决了这个问题,我在这里提出解决方案。
问题出在我公司的扩展中,该扩展使用了与jquery自动完成相关联的focus()事件。下面我展示了原始事件源代码:
$(element).focus(function(){
if ($(element).autocomplete("widget").is(":visible"))
return;
$(element).data("uiAutocomplete").search($(this).val());
});
下面是新的源代码,我将focus()更改为focusin()和focusout():
$(element).focusin(function () {
if ($(element).val().length == 0) {
if ($(element).autocomplete("widget").is(":visible"))
return;
$(element).data("uiAutocomplete").search($(this).val());
}
});
$(element).focusout(function () {
if ($(element).autocomplete("widget").is(":hidden"))
return;
});
有了这个,我可以解决IE8的错误。