我确定问题出在您使用的 HTML 页面的编码中。我试图重现该问题并打开一个以 ANSI 编码保存的旧演示。在我将测试插入yapı
数据并保存后,我可以重现该问题,但验证代码表明该字符串yapı
已保存为yapi
ANSI 编码。然后我使用记事本打开相同的演示(我在 Windows 计算机上工作)重复相同的操作,并使用 SaveAs 来选择 UTF-8 编码。现在可以看到真正yapı
的字符串显示在网格中而不是yapi
以前,我可以成功过滤字符串。当然,我<meta charset="utf-8">
在两个实验中都有。
因此,您应该验证不仅<meta charset="utf-8">
存在于<head>
您的 HTML 页面中,而且数据也采用 UTF-8 编码。在嵌入数据的情况下(如我的实验中),文件需要以 UTF-8 格式保存。
更新:评论中的讨论表明主要问题是土耳其文本的不区分大小写过滤。
这个问题对我来说绝对是新问题,但土耳其语有两个 i
:一个有 point over i
,另一个没有point ı
。两者i
都有相应的大写I
:İ
和I
。所有信息都与许多其他语言没有什么不同。主要问题在于 4 个字符的 Unicode 表示的选择:土耳其字符 i
和I
使用相同的代码,如拉丁字符:U+0069
和U+0049
. 只有字符ı
和İ
将被映射到U+0131
和U+0130
(见这里)。这种映射使得无法实现不区分大小写的比较或 JavaScript 函数.toUpperCase()
和.toLowerCase()
。如果输入文本包含拉丁字母i
,则该函数.toUpperCase()
应将其转换为I
,但土耳其语是错误的,应该İ
改为。土耳其语文本和英语文本应以同样的方式.toLowerCase()
生成。ı
i
因此,第一个重要信息:在不了解输入语言的情况下,不可能实现一个通用版本的不区分大小写比较。
好的。现在回到问题。如何在土耳其语文本中实现不区分大小写的搜索?在 4.7.1 版中更改 jqGrid 的许可协议后,我继续以 free jqGrid 的名义开发它的免费版本(在 MIT 和 GPL v2 许可下)。我在免费 jqGrid 的第一个版本:4.8 版中实现了许多新功能。wiki 文章中描述的“自定义过滤”功能可以帮助实现。
基于该功能,我创建了以下演示。我在实现过程中对free jqGrid的代码做了一些小bug修复。http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js
因此,我在演示中使用了来自 GitHub ( ) 的最新资源(阅读有关 URL 的wiki )。
我在 jqGrid 中使用了以下选项
ignoreCase: false,
customSortOperations: {
teq: {
operand: "==",
text: "Turkish insensitive \"equal\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData === searchValue;
}
},
tne: {
operand: "!=",
text: "Turkish insensitive \"not equal\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData !== searchValue;
}
},
tbw: {
operand: "^",
text: "Turkish insensitive \"begins with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.substr(0,searchValue.length) === searchValue;
}
},
tbn: {
operand: "!^",
text: "Turkish insensitive \"does not begin with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.substr(0,searchValue.length) !== searchValue;
}
},
tew: {
operand: "|",
text: "Turkish insensitive \"end with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(),
searchLength = searchValue.length;
return fieldData.substr(fieldData.length-searchLength,searchLength) === searchValue;
}
},
ten: {
operand: "!@",
text: "Turkish insensitive \"does not end with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(),
searchLength = searchValue.length;
return fieldData.substr(fieldData.length-searchLength,searchLength) !== searchValue;
}
},
tcn: {
operand: "~",
text: "Turkish insensitive \"contains\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.indexOf(searchValue,0) >= 0;
}
},
tnc: {
operand: "!~",
text: "Turkish insensitive \"does not contain\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.indexOf(searchValue,0) < 0;
}
}
}
该选项customSortOperations
为土耳其语文本的不区分大小写比较定义了新的自定义操作。要使用该选项,只需searchoptions
为包含土耳其语文本的列指定操作:
searchoptions: { sopt: ["tcn", "tnc", "teq", "tne", "tbw", "tbn", "tew", "ten"] }
结果,过滤使用“tcn”(Turkish insensitive "contains"
)作为默认过滤操作。如果使用searchOperators: true
选项,filterToolbar
则可以选择另一种搜索操作。我希望以上所有自定义比较操作都是正确的,并且可以在土耳其网格中使用。
更新 2:我发现了另一个有趣的实现选项:支持参数的方法localeCompare 。我在谷歌浏览器中测试过
"i".localeCompare("İ", "tr", { sensitivity: "base" }) === 0
"i".localeCompare("I", "tr", { sensitivity: "base" }) === 1
"ı".localeCompare("I", "tr", { sensitivity: "base" }) === 0
"ı".localeCompare("İ", "tr", { sensitivity: "base" }) === -1
或者
"i".localeCompare("İ", "tr", { sensitivity: "accent" }) === 0
"i".localeCompare("I", "tr", { sensitivity: "accent" }) === 1
"ı".localeCompare("I", "tr", { sensitivity: "accent" }) === 0
"ı".localeCompare("İ", "tr", { sensitivity: "accent" }) === -1
但是 IE11 中的相同测试与有关浏览器兼容性的信息相反。IE11 中的所有上述localeCompare
返回调用。0
可以使用另一个值sensitivity
来获得预期的结果。IE9 会为上述调用返回 1 或 -1 localeCompare
。我想它只考虑第一个参数并忽略"tr", { sensitivity: "base" }
部分。Chrome 中的结果看起来如此

一个在 Firefox 中具有相同的结果

但不在 IE11 中

另一种选择是使用ECMAScript 国际化 API类Intl.Collator(参见ecma-402和此处),例如
new Intl.Collator("tr", { sensitivity: "base" }).compare("i", "İ")
例如,但 IE 在这种情况下似乎也好不到哪里去。
无论如何,我认为可以通过包括浏览器检测部分来改进上述解决方案,该部分为比较的实现选择闭包以及customSortOperations
稍后内部最佳实现的使用。尽管如此,上面的代码是安全的,但它的原因可能不是那么优雅。