在IE8、IE9和IE10中使用javascript更改元素类名时可能出现错误
注意:我之前有一个类似的问题,我现在试图删除它。我原以为问题与.NETWebBrowser控件有关,但与IE有关 下面的代码是一个.htm文件的内容,该文件仅显示3个可单击的项目。单击每个项目时,javascript方法会将其背景更改为蓝色,并将以前选择的项目背景更改为白色 这就是问题所在,它只出现在IE8、9和10中。它在FF、chrome中工作,我使用IE10开发者预览演示了它在IE5和IE7中的工作 单击项目1,然后单击项目1.1-项目1.1高亮显示,但项目1未取消高亮显示 但是(向上移动文档树):在IE8、IE9和IE10中使用javascript更改元素类名时可能出现错误,javascript,css,internet-explorer,internet-explorer-9,jscript,Javascript,Css,Internet Explorer,Internet Explorer 9,Jscript,注意:我之前有一个类似的问题,我现在试图删除它。我原以为问题与.NETWebBrowser控件有关,但与IE有关 下面的代码是一个.htm文件的内容,该文件仅显示3个可单击的项目。单击每个项目时,javascript方法会将其背景更改为蓝色,并将以前选择的项目背景更改为白色 这就是问题所在,它只出现在IE8、9和10中。它在FF、chrome中工作,我使用IE10开发者预览演示了它在IE5和IE7中的工作 单击项目1,然后单击项目1.1-项目1.1高亮显示,但项目1未取消高亮显示 但是(向上移动
单击项目1,然后单击根-没问题
单击项目1,1,然后单击项目1-没问题 现在,如果我将javascript selectElement(e)方法切换为先取消选择,然后选择,那么问题就会变成: 单击项目1.1,然后单击项目1-单击项目1和显示蓝色背景之间存在明显延迟 如果删除图像标签,问题就会消失。 将项目从视图中滚出,然后再将其滚回视图可以修复渲染。不幸的是,调用Invalidate或Update并不能解决问题。 将先前选择的元素的显示样式切换为“无”,然后再切换回可解决问题-除非用户错误地选择了节点文本(例如双击) 我尝试过的一些事情:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-GB">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
span, img {margin:0;padding:0}
.child {margin-left: 10px;}
.normal {background-color: White;}
.selected {background-color: blue; color: white;}
</style>
<script type="text/javascript">
var selectedElement;
function selectElement(e) {
/* Select new element */
e.attributes["class"].value = "selected";
/* Unselect currently selected */
if (selectedElement) {
selectedElement.attributes["class"].value = "normal";
}
selectedElement = e;
}
</script>
</head>
<body>
<div>
<div class="child"><label id="root_id" class="normal" onclick="selectElement(this)">ROOT</label></div>
<div class="child"><img alt="img" src="temp/expand_tree_20x8.png" />
<label id="item1_id" class="normal" onclick="selectElement(this)">ITEM 1</label>
<div class="child"><img alt="img" src="temp/expand_tree_20x8.png" />
<label id="item1_1_id" class="normal" onclick="selectElement(this)">ITEM 1.1</label>
</div>
</div>
</div>
</body>
</html>
span,img{边距:0;填充:0}
.child{左边距:10px;}
.normal{背景色:白色;}
.所选{背景色:蓝色;颜色:白色;}
var选择元素;
功能选择元件(e){
/*选择新元素*/
e、 属性[“类”]。value=“选定”;
/*取消选择当前选定的*/
如果(已选择元素){
selectedElement.attributes[“class”].value=“normal”;
}
selectedElement=e;
}
根
项目1
项目1.1
这可能无法解决您面临的重画问题,但这太长了,无法包含在评论中
变量e
通常表示事件对象,而不是dom对象。因此,当其他开发人员查看您的代码时,他们会感到困惑。将其更改为elem、ele、domObj或除e以外的任何内容
其次,设置类名的方式很奇怪。我希望看到className
var selectedElement;
function selectElement(elem) {
/* Select new element */
elem.className = "selected";
/* Unselect currently selected */
if (selectedElement) {
selectedElement.className = "normal";
}
selectedElement = elem;
}
最好使用一些辅助函数来添加和删除类,这样就可以在元素上有多个类
function hasClass(elem, cls) {
return elem.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(elem, cls) {
if (!this.hasClass(elem, cls)) elem.className += " " + cls;
}
function removeClass(elem, cls) {
if (hasClass(elem, cls)) {
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
elem.className = elem.className.replace(reg, ' ');
}
}
var selectedElement;
function selectElement(elem) {
/* Select new element */
addClass(elem, "selected");
/* Unselect currently selected */
if (selectedElement) {
removeClass(selectedElement, "normal";
}
selectedElement = elem;
}
有时,读取高度会强制重新绘制,因此请尝试这样做
var selectedElement;
function selectElement(elem) {
/* Select new element */
addClass(elem, "selected");
/* Unselect currently selected */
if (selectedElement) {
removeClass(selectedElement, "normal";
}
/* Try to force a redraw */
//elem.style.display = "none"; //if just reading offsetHeight, does not work try uncommenting the two lines of code.
var redrawFix = elem.offsetHeight;
//elem.style.display = "block"; //or inline or whatever
selectedElement = elem;
}
令人惊讶的是,事实并非如此。IE10开发者预览允许您将模式切换到IE5、IE7、IE8、IE9和IE10。因为某种原因没有IE6。显然,我并不关心IE5的兼容性,我只是惊讶地看到它在那种模式下工作。旁注:使用jQuery也可以消除这个bug。有趣的是,我会尝试一下。(虽然这需要一段时间,因为我对jQuery不太熟悉)。在FF和chrome中进行测试时,我一直在通过属性设置类名,作为一种临时措施,只是因为我知道这是有效的,并且不确定在其他浏览器中是“className”还是其他什么。感谢添加和删除类的代码。很明显,我的示例代码已精简,但我的待办事项列表中有一个添加/删除类。我提到更改显示样式确实可以解决OP中的问题,但我发现并不总是这样。当我首先取消选择上一个元素,然后选择新元素时,如果我通过调用单击来选择新元素,则不会选择新元素(即,用户不会手动选择它)。然而。。。使用所有3条线,包括offsetHeight(我也单独尝试过),确实有效!我将暂缓将此作为正确答案,因为我仍然怀疑我做错了什么。或者在IE8、9和10中被破坏。仅供参考:读取偏移量会强制重新绘制,因为必须计算值。我意识到这一点,但为什么还需要更改显示?