这次总算把系统前台中一个关于光标定位的bug给解决了~~~这里的文本框选择的对象在JS 的API文档中貌似没有仔细讲,而且犀牛书中也对此只是一笔带过。。。网上查了蛮多的资料,下面总结一下废话不说,直奔代码:(以jQ插件写的,外闭包省略)
/** * 设置光标指针工具函数 * @param {mix} pos */ $.fn.setFocus = function (pos){ var DOMele = $(this).get(0); var _pos = 0; if(typeof pos == 'string'){ if(pos == 'first'){ _pos = 0; }else if(pos == 'last'){ _pos = DOMele.value.length; } }else if(typeof pos == 'number'){ _pos = pos; } if (document.all && DOMele.createTextRange) {//IE var range = DOMele.createTextRange(); range.move("character",_pos); //range.moveStart('character',_pos); //range.collapse(true); range.select(); }else {//FF if (DOMele.setSelectionRange) { DOMele.setSelectionRange(_pos, _pos); DOMele.focus(); } } return this; };
在选择对象中包含有两种不兼容的对象,IE和FF,chrome兼容两种(还有一种DOM L2中定义的对象,貌似不常用,这里略讲)
IE开始:
IE的选择对象通过下面的语句创建:
var range = DOMele.createTextRange();
生成的是一个TextRange范围对象,后面的一系列操作都得和它有关
这个对象含有一些属性和方法如下:(参考原文参照此:http://hi.baidu.com/longtao_1986/blog/item/c95cae30fa666410ebc4afbb.html)
属性
boundingHeight 获取绑定TextRange对象的矩形的高度
boundingLeft 获取绑定TextRange 对象的矩形左边缘和包含TextRange对象的左侧之间的距离
offsetLeft 获取对象相对于版面或由offsetParent属性指定的父坐标的计算左侧位置
offsetTop 获取对象相对于版面或由offsetParent属性指定的父坐标的计算顶端位置
htmlText 获取绑定TextRange对象的矩形的宽度
text 设置或获取范围内包含的文本
方法
moveStart 更改范围的开始位置
moveEnd 更改范围的结束位置
collapse 将插入点移动到当前范围的开始或结尾
move 折叠给定文本范围并将空范围移动给定单元数
execCommand 在当前文档、当前选中区或给定范围上执行命令
select 将当前选择区置为当前对象
findText 在文本中搜索文本并将范围的开始和结束点设置为包围搜索字符串。
这里我们最常用到的无非是这么几个方法moveStar,moveEnd ,collapse,move,select 等
moveStar,moveEnd ,move这几个方法的格式形如:
move("Unit"[,count])
这边的”Unit“可以是它指定的单位有character(字符)、word(词)、sentence(段落)、textedit。
collapse是定位在开始处或者结束处,以boolean 的传入
而据我试验——在IE下确定光标时可以有两种方法:
var range = DOMele.createTextRange(); range.move("character",_pos); range.select();
上面这种是直接用move传入
var range = DOMele.createTextRange(); range.moveStart('character',_pos); range.collapse(true); range.select();
上面这种是用moveStart定位,配合用collapse传入true
有一点要注意最后的select也是直接用范围对象引用,此间不与文本框DOM对象交互,恰恰这点是和FF完全不同的
IE的选择对象的使用,浅浅的讲到这里:
下面是FF和chrome的
相对于IE的复杂,FF的会稍许简单~
首先是不同的创建方法:
DOMele.setSelectionRange(_pos, _pos);
用一个DOM对象的成员函数形式setSelectionRange创建,其中传入首末的光标指针地址
这里是我要显示光标,所以把首末设成一样的。
最后选择的话于IE不同:直接以DOM对象成员方法focus聚焦到文本框
综合而言FF的比较符合人对编程的操作习惯,而IE的或多或少有点生硬~
下面来个大点的,以后等我研究透caretPos这个玩意再更新~~哈哈(以前从网上c的,后来因为需求有变被我改了很多)
/** * 插入tagTpl文字内容 * @param {String} tagTpl 需要插入的文本模板 * @param {Boolean} selectAble 是否需要选中 */ $.fn.insertAtCaret = function(tagTpl,selectAble){ var textObj = $(this).get(0); if (document.all && textObj.createTextRange && textObj.caretPos) { var caretPos = textObj.caretPos; caretPos.text = caretPos.text.charAt(caretPos.text.length - 1) == "" ? tagTpl + "" : tagTpl; var re = eval("/" + tagTpl + "/i"); var startPos = textObj.value.search(re); var endPos = textObj.innerHTML.length; var endPosOffset = -(endPos - startPos - tagTpl.length) - 1; var range = textObj.createTextRange(); var sel = range.duplicate(); if(selectAble){ sel.moveStart("character", startPos + 1); sel.moveEnd("character", endPosOffset); }else{ sel.move("character", endPos); } sel.select(); }else { if (textObj.setSelectionRange) { var rangeStart = textObj.selectionStart; var rangeEnd = textObj.selectionEnd; var tempStr1 = textObj.value.substring(0, rangeStart); var tempStr2 = textObj.value.substring(rangeEnd); textObj.value = tempStr1 + tagTpl + tempStr2; var len = tagTpl.length; if (selectAble) { textObj.setSelectionRange(rangeStart + 1, rangeStart + len - 1); }else{ textObj.setSelectionRange(rangeStart + len, rangeStart + len); } textObj.focus(); }else { if (document.all && textObj.createTextRange) { textObj.value += tagTpl; var re = eval("/" + tagTpl + "/i"); var startPos = textObj.value.search(re); var endPos = textObj.innerHTML.length; var endPosOffset = -(endPos - startPos - tagTpl.length) - 1; var range = textObj.createTextRange(); var sel = range.duplicate(); if (selectAble) { sel.moveStart("character", startPos + 1); sel.moveEnd("character", endPosOffset); } else { sel.move("character", endPos); } sel.select(); } else { textObj.value += tagTpl } } } return this; };