《关键字选取三步走:第二步,集成textarea选中与效果》

首先是选中效果的思路:

  通过构建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;
    }
OK。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

进入正题:

 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) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎

转载于:https://my.oschina.net/mahaisong/blog/140999

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值