首先是选中效果的思路:
通过构建DIV,对DIV中进行append元素,输入时是input控件,输入完成后,input控件隐藏,显示对应span(好看,带样式)的信息,点击修改时,删除span,input控件显示,修改input中的值。
看其源码有几处好玩的地方:
1. 通过JQ的插件方法, 然后使用$.extend 合并初始化变量。 这样用户的参数很容易就被JS中使用。
$.fn.extend({ tabControl: function(options, tags) { //初始化参数变量 var defOpt = { initTabCount: 1, maxTabCount: 20, tabMaxLen: 10, tabW: 150, tabH: 15, tipTOffset: 5, tipLOffset: 0 }; //初始化构造函数 var opts = $.extend(defOpt, options);//参数变量,用户设置变量值。 合并:用户设置值替换初始参数值。 //初始化标签内容。用户填写。 var _tags = [];//当前录入关键字集合。 if (tags) { tags = tags.replace(/[^A-Za-z0-9_,\u4E00-\u9FA5]+/gi, "").replace(/^,+|,+$/gi, "");//将非中英文、数字、下划丝、逗号的其他字符都去掉,且不能以逗号开头与结束 _tags = tags.split(','); } //初始标签过多省略处理。 _tags = _tags.length > opts.maxTabCount ? _tags.slice(0, opts.maxTabCount - 1) : _tags; |
2. 直接通过构造对象就返回,通过1初始的构造,在返回中生成效果。在元素上存放数据,返回jQuery对象。
//构造返回对象。 --每一个tag元素都执行,这里就一个div。 return this.each(function() { var jqObj = $(this); for (var i = 0; i < opts.initTabCount; i++) { initTab(jqObj, i); } jqObj.data("isInit", true); jqObj.click(function() { $("input[type='text'][name='tabinput']", jqObj).each(function() { if ($(this).val() == "") { $(this).focus(); return false; } }); }); }); |
3.我没想到PUSH方法,本来想着用数组。 看来还是对JS不深入。
getTabVals: function() {//获取当前容器所生成的tab值,结果是一维数组 var obj = $(this); var values = []; obj.children("span[name=\"tab\"][id^=\"radius\"]").find("b").text(function(index, text) { //alert(index);0.1.2 var checkReg = /[^A-Za-z0-9_\u4E00-\u9FA5]+/gi; values.push(text.replace(checkReg, "")); }); return values; } |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
进入正题:
1.textarea选中
搞了很长时间终于把IE和火狐的弄好。 功能: textarea选中弹出div,div确认选中信息。
// JavaScript Document var SWord = { text: '', Start: 0, End: 0 }; var rect = { left: -1, top: -1, width: -1, height: -1, start_left: -1 }; function ptInRect(rect, pt) { if (pt.x > rect.left && pt.x < rect.left + rect.width && pt.x > rect.start_left) if (pt.y > rect.top && pt.y < rect.top + rect.height) return true; return false; } //得到鼠标的位置 function getMouse(ev) { // if (ev.pageX || ev.pageY) { // return { // x: ev.pageX, // y: ev.pageY // }; // } return { x: ev.clientX + document.body.scrollLeft - document.body.clientLeft, y: ev.clientY + document.body.scrollTop - document.body.clientTop }; } var isin = true; (function($) { $.fn.extend({ "selectText": function(value) { value = $.extend({ "delays": 800 }, value); var $this = $(this); //鼠标抬起进,获取选择文字的字数。并根据字数,是否显示弹出层 $this.mouseup(function(event) { var str = ""; if (document.selection) { // IE 用简单的方式,记录坐标 var str = document.selection.createRange(); var position = getMouse(event); if (ptInRect(rect, position)) { $this.next("div").hide(); rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; } else { if (str.text.length > 1) { isin = false; rect.left = str.boundingLeft;//对象左距离 rect.top = str.boundingTop; rect.width = str.boundingWidth; rect.height = str.boundingHeight; rect.start_left = str.offsetLeft;//版面左 rect.end_left = str.offsetTop;//版面顶 $this.next("div").css({ "top": event.pageY + 10, "left": event.pageX + 10 }).delay(value.delays).show(); SWord.word = str.text; } else { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; $this.next("div").hide(); } } } else { var p1 = this.selectionStart; var p2 = this.selectionEnd; if (p1 || p1 == '0') { if (p1 != p2) { //选中 if (p1 >= SWord.Start && p2 <= SWord.End) { SWord.Start = 0; SWord.End = 0; SWord.word = ''; $this.next("div").hide(); }else { p1=p1<p2?p1:p2; p2=p2>p1?p2:p1; SWord.Start = p1; SWord.End = p2; SWord.word = this.value.substring(p1, p2); $this.next("div").css({ "top": event.pageY + 10, "left": event.pageX + 10 }).delay(value.delays).show(); } } else //点击 { SWord.Start = 0; SWord.End = 0; SWord.word = ''; $this.next("div").hide(); } } } }); //点击文档任何位置,让显示的层消失 $(document).click(function() { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; $this.next("div").hide(); }); $this.next("div").click(function() { rect.left = -1; rect.top = -1; rect.width = -1; rect.height = -1; rect.start_left = -1; rect.end_left = -1; isin = true; alert(SWord.word); window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); }); //阻止冒泡,防止第一次选中文字时,由于冒泡,而触发了$(document).click事件 $this.click(function(event) { event.stopPropagation(); }); return $this; } }) })(jQuery) |
这样就很好的实现我想要的功能了。 此例子可以用来多个同时使用。 当然 div绑定,等等都还有需要修改的地方,但是次demo还是可以的。 在做的同时,搞了很多的不同功能。学习了很多。
2.选中并入显示
主要是把选中并入到 显示的方法里面去。 同时修改和扩展显示的方法。还有删除的方法也要修改。存入的方式也要正则表达式的方式去做。利用正则表达式去匹配字串,做删除和添加等操作。同时修改的方法也要做成字符串替换的方式来操作HTMLdom元素。
当时想到的方法:
利用JS得到IE中的开始位置, 通过字串的长度,得到结束位置。
可是这样还必须对每次的鼠标点击求位置,于是就没使用。
function _getStart(elem) { // 获取光标在文本框的位置--位置容易弄错。 虽然得到第一个匹配成功的,但是不一定就是我选择的。 var index = 0; if (document.selection) {// IE Support elem.focus(); var Sel = document.selection.createRange(); if (elem.nodeName === 'TEXTAREA') {//textarea var Sel2 = Sel.duplicate(); Sel2.moveToElementText(elem); var index = -1; while (Sel2.inRange(Sel)) { Sel2.moveStart('character'); index++; }; } else if (elem.nodeName === 'INPUT') {// input Sel.moveStart('character', -elem.value.length); index = Sel.text.length; } } else if (elem.selectionStart || elem.selectionStart == '0') { // Firefox support index = elem.selectionStart; } return (index); } |
本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎