日期:2014-05-16  浏览次数:20549 次

JavaScript Table排序 2.0 补充
原贴请看这里

由于不能修改只好另开一帖

效果预览和程序说明请看这里

下载测试代码

补充内容包括
增加bool类型比较;
修正ie6/7的radio/checkbox状态恢复bug;
增加自定义取值函数。

【radio/checkbox的checked状态bug】

可以用ie6/7测试下面代码:
<div id="c">
<input type="checkbox" id="a" />
<input name="b" type="radio" id="b" />
</div>
<input type="button" value="click" id="btn" />
<script>
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementById("c");
document.getElementById("btn").onclick = function(){
  c.appendChild(a);
  c.appendChild(b);
  var o1 = document.createElement("input");
  o1.type = "checkbox"; o1.checked = true;
  c.appendChild(o1);
  var o2 = document.createElement("input");
  o2.type = "radio"; o2.checked = true;
  c.appendChild(o2);
}
</script>

先点选checkbox和radio,然后点击按钮,在ie6会发现checkbox和radio都恢复到没有点选的状态,ie7好点只是radio有问题。
而且新插入的checkbox和radio虽然checked都设置成true,但显示出来还是没有选择的状态。
这里其实都是一个问题,checkbox和radio在一些dom操作之后(例如这里的appendChild),checked会自动恢复成defaultChecked的状态。
创建元素的问题可以参考这里。
程序中tr在排序后会用appendChild重新插入文档,结果就会导致上面的问题了,解决方法暂时想到三个:
1,在appendChild之前修改defaultChecked。
针对appendChild后会自动恢复成defaultChecked,那我们就在appendChild前把defaultChecked修改成当前的checked值。
这个解决方法不错,只要appendChild之前扫一遍表单控件就行,但问题是这会影响到reset的结果,因为reset之后checkbox/radio的checked就会恢复成defaultChecked的值,如果修改了defaultChecked那reset就失去了效果。
2,在appendChild之前保存checked的状态,并在appendChild之后恢复。
要实现这个也有两个方法,一个是用一个数组或对象来保存checkbox/radio当前的checked值,在appendChild之后找出对应的值并设置。
另一个是直接把checkbox/radio当前的checked值保存到该控件的一个自定义属性中,在appendChild之后再获取并设置。
两个方法都要扫两次表单控件,后面的方法比较方便。
3,在appendChild之前找出checked跟defaultChecked不相等的控件,并在appendChild之后重新设置这些控件。
这个方法比前一个稍好,只要在appendChild之前扫一遍控件,并筛选出需要修正的(checked跟defaultChecked不相等的),在appendChild之后设置checked为defaultChecked的相反值就行了。

程序用的是第3个方法,在appendChild之前用GetChecked方法获取要修正的checkbox/radio集合:
  GetChecked: function() {
  this._checked = Filter(this.tBody.getElementsByTagName("input"), function(o){
  return ((isIE6 && o.type == "checkbox") || o.type == "radio") && o.checked != o.defaultChecked;
  });
  },

在appendChild之后用SetChecked重新设置checked值:
  SetChecked: function() {
  forEach(this._checked, function(o){ o.checked = !o.defaultChecked; });
  }
但这样效率还是比较低,如果有更好的方法记得告诉我啊。

ps:感谢xingqiliudehuanghun告诉我radio/checkbox的checked状态bug

------解决方案--------------------
观摩下.顺便拿沙发.
------解决方案--------------------
好贴
------解决方案--------------------
收藏一下
------解决方案--------------------
楼主一般都是很用心的在做东西 ,单凭这点 ,就值得我们去学习
------解决方案--------------------
探讨
楼主一般都是很用心的在做东西 ,单凭这点 ,就值得我们去学习

------解决方案--------------------
~jF
------解决方案--------------------
不错 好贴
------解决方案--------------------
好贴,友情帮顶~~
------解决方案--------------------
楼主一般都是很用心的在做东西 ,单凭这点 ,就值得我们去学习
------解决方案--------------------