Posted by Mr.Think on 12/23/2010
实际应用中, 获取元素样式在实际应用中一定常用到, 若是纯粹html中, 直接elem.style.attr就可获取, 但更多的时候我们是要从CSS中获取元素的最终样式属性.所以, 我们得利用IE的currentStyle和W3C的getPropertyValue获取.
elem.style.attr获取样式的方法就不说了. 先来看currentStyle方法, 此对象ie专属, 代表了在全局样式表、内嵌样式和 HTML 标签属性中指定的对象格式和样式. IE下通过它, 就可以获取元素的CSS属性值.
而针对其他标准浏览器, W3C也提供了一个方法getPropertyValue, 此方法, 稍有点复杂, 首先要通过document.defaultView.getComputedStyle获得CSS的样式对象, 然后通过该对象的getPropertyValue获取属性值.
上述两种方法, 无论IE还是W3C的, 有一点是相同的, 它们所获取的是元素CSS属性最终值. 这一点与CSS的优先级是相同的.
有一点不同的是, IE的方法是通过CSS属性的驼峰式名(如textAlign)获取, 而W3C的方法是通过元素CSS原来的属性名(如text-align)获取的, 所以, 在使用W3C方法时, 需要对CSS属性名做个简单的处理.
基于此, 我们可以封装一个获取元素属性值的方法, 如下:
function attrStyle(elem,attr){
if(elem.style[attr]){
//若样式存在于html中,优先获取
return elem.style[attr];
}else if(elem.currentStyle){
//IE下获取CSS属性最终样式(同于CSS优先级)
return elem.currentStyle[attr];
}else if(document.defaultView && document.defaultView.getComputedStyle){
//W3C标准方法获取CSS属性最终样式(同于CSS优先级)
//注意,此法属性原格式(text-align)获取的,故要转换一下
attr=attr.replace(/([A-Z])/g,'-$1').toLowerCase();
//获取样式对象并获取属性值
return document.defaultView.getComputedStyle(elem,null).getPropertyValue(attr);
}else{
return null;
}
}
记得精通JavaScript一书中获取元素位置那一节(忘了是第6还是第7章), 有获取元素样式属性值更详细的解释. 第一次知道document.defaultVies.getComputedStyle就是从这本书来的. 很棒的一本书, 有兴趣的朋友话一定要看看.
JavaScript
Posted by Mr.Think on 12/12/2010
日常项目中, 对于列表类文章或数据, 大概都会用到checkbox的全选或全不选的功能, 以前的项目中也写过checkbox的选择js, 但都没有整理过. 正好前几天一个兄弟遇到了这个问题, 索性, 我花了点时间, 用原生JS与jQuery分别写了一个版本, 考虑到使用时灵活性问题, 未封装, 需要的童鞋使用时自行改下相关参数.

功能介绍点此查看DEMO
1. 全选/全不选 选框一体实现, 即列表中选框的状态与全选/全不选框前的选框状态一致;
2. 自动更改 全选/全不选 选框的状态, 即列表中选框都选中时, 全选/全不选 选框也选中, 反之亦然;
3. 列表行内点击也可选中行内的checkbox, 并与1,2中的功能联动.
另,本文重在写全选, 鼠标划入划出背景变色为简易实现, 更加完善的请参考: http://mrthink.net/javascript-tagnames-highlight/.
原生JS版本核心代码
var js_chk = document.forms['js'].chk_can;
var jsitems = document.forms['js'].jsitems;
var jsrows = document.getElementById('js').getElementsByTagName('dd');
//判断选中个数与实际选框个数实现全选/全不选框的状态
var chk_canle = function(){
var checkedLen = 0;
//计算列表中选中状态的选框个数
for (var m = 0; m < jsitems.length; m++) {
if (jsitems[m].checked) {
checkedLen += 1;
}
}
//判断选中个数与实际个数是否相同,以确定全选/全不选状态
for (var m = 0; m < js_chk.length; m++) {
js_chk[m].checked = (jsitems.length == checkedLen);
}
}
//全选与全不选一体实现
for (var i = 0; i < js_chk.length; i++) {
js_chk[i].onclick = function(){
//列表中选框与全选选框统一状态
for (var m = 0; m < jsitems.length; m++) {
jsitems[m].checked = this.checked;
}
//全选选框统一状态
for (var m = 0; m < js_chk.length; m++) {
js_chk[m].checked = this.checked;
}
}
}
//列表中选框点击
for (var i = 0; i < jsitems.length; i++) {
jsitems[i].onclick = function(e){
//阻止冒泡,避免行点击事件中,直接选择选框无效
e && e.stopPropagation ? e.stopPropagation() : window.event.cancelBubble=true;
chk_canle();
}
}
//行内点击
for (var i = 0; i < jsrows.length; i++) {
jsrows[i].onclick = function(){
//行内点击时,行内的选框状态为原状态取反
this.getElementsByTagName('input')[0].checked = !this.getElementsByTagName('input')[0].checked;
chk_canle();
}
}
jQ版本核心代码
var _jq_chk = $('#jq>dl>dt>label>:checkbox');
var _jqitems = $(':checkbox[name=jqitems]');
var _rows = $('#jq>dl>dd');
//全选与全不选一体实现
_jq_chk.click(function(){
//列表中选框和全选选框统一状态
_jqitems.add(_jq_chk).attr('checked', this.checked);
});
//选框的点击事件
_jqitems.click(function(e){
//阻止冒泡,避免行点击事件中,直接选择选框无效
e.stopPropagation();
//判断选中个数与实际个数是否相同,以确定全选/全不选状态
_jq_chk.attr('checked', _jqitems.size() == _jqitems.filter(':checked').size());
});
//点选行时选中行内的checkbox
_rows.bind({
mouseenter: function(){
$(this).addClass('hover');
},
mouseleave: function(){
$(this).removeClass('hover');
},
//点选
click: function(){
//行内点击时,行内的选框状态为原状态取反
$(this).find(':checkbox').attr('checked', !$(this).find(':checkbox').get(0).checked)
//判断选中个数与实际个数是否相同,以确定全选/全不选状态
_jq_chk.attr('checked', _jqitems.size() == _jqitems.filter(':checked').size());
}
});
JavaScript, jQuery
Posted by Mr.Think on 12/06/2010
计时器setTimeout()与setInterval()是原生JS很重要且用处很多的两个方法, 但很多人一直误以为是相同的功能: 间隔时间重复执行传入的句柄函数. 但实际上, 并非如此, 既然JS给出了两个不同的命名, 肯定有其迥异之处.
先来看看两者JS手册及英文词典上的解释:
JS手册»setTimeout() : 用于在指定的毫秒数后调用函数或计算表达式;
英文释义»timeout() : 超时;暂时休息;工间休息;
JS手册»setInterval() : 按照指定的周期(以毫秒计)来调用函数或计算表达式. 会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭;
英文释义»interval() : 间隔;间距;幕间休息;
不难看出, 只要我们仔细体会JS手册及命名释义, 就能很容易的区分开两者的区别. 简单的说, 两才的区别在于, setTimeout()方法是在等待指定时间后执行函数, 且只执行一次传入的句柄函数. setInterval()方法是每指定间隔时间后执行一次传入的句柄函数,循环执行直至关闭窗口或clearInterval().
为了使迷惑者更容易理解, 特意写了个例子: 点此查看DEMO
至于用法, 就不用多说了, 明白两者区别后, 该知道怎么取舍了.
JavaScript
Posted by Mr.Think on 10/22/2010
最近在为项目写登录注册系列页面, 表单验证无疑是不可缺少的部分, 在这个jQ插件满天飞的web年代, 表单验证倒也不是难事. 但再好的插件, 也并不能做到十全十美, 比如这次用到的我先前介绍过的Vanadium表单验证插件, 因为是E文中不存在占2个字符的字, 所以, 区分中英文字符就得自己扩展. 本文就将介绍两种区分中英文字符的方法: 利用正则和charCodeAt方法区分中英文字符.点此查看DEMO
正则无疑是最强大的判断各种条件的方法, 最近也在研习它, 虽然枯燥, 但仍有乐趣. 用它来判断一个双字节的中文字符也是轻而易举地. 而判断中文字符, Mr.Think也是非常推荐用这种方法的, 简单且执行效率高.
核心代码如下:
regExpForm.onblur=function(){
entryVal=this.value;
entryLen=entryVal.length;
cnChar=entryVal.match(/[^\x00-\x80]/g);//利用match方法检索出中文字符并返回一个存放中文的数组
if(cnChar!=null){
entryLen+=cnChar.length;//算出实际的字符长度
}
}
第二种方法是通过charCodeAt()方法判断Unicode码值, 若大于255即为中文字符(为什么? 请Google). Mr.Think并不建议用这种方法的, 它的执行效率没有正则高, 也没有正则简单.
核心代码如下:
entryVal=this.value;
entryLen=entryVal.length;
for(var i=0;i<entryVal.length;i++){
if(entryVal.charCodeAt(i)>255){//遍历判断字符串中每个字符的Unicode码,大于255则为中文
cnArr.push(entryVal[i]);//讲符合条件的值插入到中文字符数组中
//注意一个小bug,push是向数组的末尾添加一个或多个元素并返回新的长度,所以未刷新的情况下反复blur会累加字符值
}
}
entryLen+=cnArr.length;
JavaScript
Posted by Mr.Think on 09/25/2010
一个随机排列元素的方法, 其实之前是在摄影页面写的一个小效果.
查看演示: 点此查看DEMO
实现方法
利用Math.random()产生随机数, 再通过sort()进行随机排列.
核心代码
function randomFun(){
var h5=document.getElementsByTagName('h5')[0]
var spanItem=document.getElementsByTagName('span');
var random=function(){return Math.random()>0.5 ? -1 : 1};//为sort()传入的随机排列参数
var spanArr=new Array();//用来存放元素的数组
var cssArr=new Array();//用来存放样式值的数组
var k,m;
for(var i=0; i<spanItem.length; i++){
spanArr.push(spanItem[i]);//将元素存入元素数组
cssArr.push(i);//将对应的下标值存入样式值数组
}
spanArr.sort(random);//打乱元素数组排列顺序
cssArr.sort(random);//打乱样式值数组排列顺序
for(k=0; k<spanArr.length; k++){
h5.appendChild(spanArr[k]);//将打乱后的元素重新插入到页面中
}
for(m in cssArr){
spanArr[m].className='color_'+cssArr[m];//将打乱后的样式加给元素
}
}
JavaScript