我最近在公司内部网站上实现了Selectivizr,因为我们需要支持IE7/8。不幸的是,我们的网站通过jQuery/AJAX进行了大量动态内容加载。
为了解决这个问题,我重载了jQuery ready函数,以便在Selectivizr执行指定的任务后重新加载它。我的代码如下所示:
$(function () {
if ($('body.ie8, body.ie7, body.comp-view8, body.comp-view7').length > 0) {
(function () {
var original = jQuery.fn.ready;
var getSelectivizr;
jQuery.fn.ready = function () {
// Execute the original method.
original.apply(this, arguments);
clearTimeout(getSelectivizr);
getSelectivizr = setTimeout(function () {
$.getScript(selectivizr);
}, 50);
}
})();
}
});
很简单。但是,一个队友最近发现了一个似乎与之相关的错误。在IE8/7中,任何动态加载到页面中的选择下拉列表(我不确定是否会影响到静态下拉列表,而且这些页面都没有这些下拉列表)都需要单击两次才能将其打开。
更具体地说,在IE8/7中,第一次单击似乎使焦点集中在下拉列表上,而第二个单击则将其打开。它是Compatibility View(兼容性 View ),实际上会瞬间打开,然后关闭。第二次单击就可以正常打开(只要您始终专注于下拉菜单)。
我以为Selectivizr所做的事情可能是个问题,因为它并不是为动态加载的内容而设计的,但是经过一点调试之后,似乎是setTimeout导致了这种奇怪的行为。
我完全不知道如何在不删除Selectivizr实现的情况下如何来解决此问题。
可能值得注意的是,如果进行了不同的AJAX调用,则setTimeout对于防止浏览器多次尝试加载Selectivizr是必要的,因为这可能会导致浏览器内部出现严重的性能问题。
注意:此问题不能准确反射(reflect)标题中所述的问题,因此我对其进行了更新以提供更好的搜索!几周后回到这个问题之后,我意识到我的最初调试使我走错了路。抱歉,我已经提供了答案,希望对您有所帮助!:)
最佳答案
因此,我终于有机会重温这个错误,而且似乎解决方案一直盯着我,因为我搞砸了最初的调试工作,所以我完全错过了它。
事实证明,这一直是一个挑剔的问题。不幸的是,对IE8及以下版本中的选择框进行任何形式的动态更改(JS)都会导致重新绘制它,从而迫使其关闭(或永远不会打开,具体取决于版本/模式)。 selectivizr的工作方式是使用JS模仿伪类的行为,将一个类离散地添加到元素中,例如“slvzr-focus”。在这种情况下,“:focus”。
这样,有意义的是仅限制选择器不应用此类补丁来选择焦点框。我的解决方案如下,尽管可能并不适用于所有人(或者,您可以简单地确保CSS中不存在“:focus”选择器,这将导致selectivizr从不触发该事件):
1)
在selectivizr.js中找到以下行:
if (!hasPatch(elm, patch)) {
if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {
cssClasses = toggleClass(cssClasses, patch.className, true);
}
}
2)
使用以下if语句将其包装:
if (!(elm.tagName == 'SELECT' && patch.className == 'slvzr-focus')) {
}
3)
完成后,该块应如下所示:
if (!(elm.tagName == 'SELECT' && patch.className == 'slvzr-focus')) {
if (!hasPatch(elm, patch)) {
if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {
cssClasses = toggleClass(cssClasses, patch.className, true);
}
}
}
希望能帮助到那里的人。
谢谢S/O!