zoukankan      html  css  js  c++  java
  • 动态获取输入框光标在页面中的位置! || 动态添加 style标签 || 获取元素样式 || 获取元素在页面中的位置

    html

    <!DOCTYPE html>
    <html>
        <head>
        <title>InputPostion</title>
        <script src="./getFocusPosition.js"></script>
        </head>
        <body>
            <textarea id="text" style=" 340px; height: 210px;"></textarea>
            <button onclick=" getPosition() ">获取焦点</button>
            <script>
                function getPosition(){
                    let textareaNode = document.getElementById("text");
                    console.log("textarea焦点位置",getFocusPosition.getInputPositon(textareaNode));
                }
            </script>
        </body>
    </html>

    getFocusPosition.js

    /**
     * getPositionApiObj 是获取输入框(textarea、input)的光标焦点位置的对象,里面包含各种api,其中getInputPositon方法会返回 光标的位置坐标
     */
    var getFocusPosition = {
        /**
        * 主方法
        * 获取输入光标在页面中的坐标
        * @param {HTMLElement} 输入框元素
        * @return {Object} 返回left和top,bottom
        */
        getInputPositon :function (elem) {
            if (document.selection) { //IE Support
                elem.focus();
                var Sel = document.selection.createRange();
                return {
                    left: Sel.boundingLeft,
                    top: Sel.boundingTop,
                    bottom: Sel.boundingTop + Sel.boundingHeight
                };
            } else {// 非IE Support
                var that = this;
                var cloneDiv ='{$clone_div}', 
                    cloneLeft ='{$cloneLeft}', 
                    cloneFocus ='{$cloneFocus}', 
                    cloneRight ='{$cloneRight}';
                var none ='<span style="white-space:pre-wrap;"> </span>';
                var div = elem[cloneDiv] || document.createElement('div'), //clone的div元素
                    focus = elem[cloneFocus] || document.createElement('span');//clone的span元素
                var text = elem[cloneLeft] || document.createElement('span');//clone的span元素
                var offset = that._offset(elem), 
                    index = this._getFocus(elem), //获取到textarea或input的光标所在的索引
                    focusOffset = { left: 0, top: 0 };
    
                if (!elem[cloneDiv]) {
                    elem[cloneDiv] = div;
                    elem[cloneFocus] = focus;
                    elem[cloneLeft] = text;
                    div.appendChild(text);
                    div.appendChild(focus);
                    document.body.appendChild(div);
                    focus.innerHTML ='|';
                    focus.style.cssText ='display:inline-block;0px;overflow:hidden;z-index:-100;word-wrap:break-word;word-break:break-all;';
                    div.className =this._cloneStyle(elem);
                    div.style.cssText ='visibility:hidden;display:inline-block;position:absolute;z-index:-100;word-wrap:break-word;word-break:break-all;overflow:hidden;';
                };
                div.style.left = this._offset(elem).left +"px";
                div.style.top = this._offset(elem).top +"px";
                var strTmp = elem.value.substring(0, index).replace(/</g, '<').replace(/>/g, '>').replace(/
    /g, '<br/>').replace(/s/g, none);
                text.innerHTML = strTmp;
    
                focus.style.display ='inline-block';
                try { focusOffset = this._offset(focus); } catch (e) { };
                focus.style.display ='none';
                return {
                    left: focusOffset.left,
                    top: focusOffset.top,
                    bottom: focusOffset.bottom
                };
            }
        },
    
        /**
        *获取光标在文本域或输入框的光标所在的位置(这里的位置是光标在第几个字符串的索引)对获取光标位置有辅助作用
        *@param {HTMLElement} 输入框元素
        */
        _getFocus:function(elem) {
            var index =0;
            if (document.selection) {// IE Support
                console.log("支持");
                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);
        },
        /**
        *获取元素在页面中位置
        *@param {HTMLElement} 输入框元素
        */
        _offset:function (elem) {
            var box = elem.getBoundingClientRect(), 
                doc = elem.ownerDocument, 
                body = doc.body, 
                docElem = doc.documentElement;
            var clientTop = docElem.clientTop || body.clientTop || 0, 
                clientLeft = docElem.clientLeft || body.clientLeft || 0;
            var top = box.top + (self.pageYOffset || docElem.scrollTop) - clientTop, 
                left = box.left + (self.pageXOffset || docElem.scrollLeft) - clientLeft;
            return {
                left: left,
                top: top,
                right: left + box.width,
                bottom: top + box.height
            };
        },
        // 克隆元素样式并返回类
        _cloneStyle: function (elem, cache) {
            if (!cache && elem['${cloneName}']) return elem['${cloneName}'];
                var className, name, rstyle =/^(number|string)$/;
                var rname =/^(content|outline|outlineWidth)$/; //Opera: content; IE8:outline && outlineWidth
                var cssText = [], sStyle = elem.style;
            
            for (name in sStyle) {
                if (!rname.test(name)) {
                    var val;
                    val =this._getStyle(elem, name);
                    if (val !==''&& rstyle.test(typeof val)) { // Firefox 4
                        name = name.replace(/([A-Z])/g, "-$1").toLowerCase();
                        cssText.push(name);
                        cssText.push(':');
                        cssText.push(val);
                        cssText.push(';');
                    };
                };
            };
            cssText = cssText.join('');
            elem['${cloneName}'] = className ='clone'+ (new Date).getTime();
            this._addHeadStyle('.'+ className +'{'+ cssText +'}');
            return className;
        },
        // 获取元素某个属性样式值
        _getStyle: 'getComputedStyle'in window ? function (elem, name) {
            return getComputedStyle(elem, null)[name];
        } :  function (elem, name) {
            return elem.currentStyle[name];
        },
        // 动态插入style标签(样式)
        _addHeadStyle: function (content) {
            var style =this._style[document];
            if (!style) {
                style =this._style[document] = document.createElement('style');
                document.getElementsByTagName('head')[0].appendChild(style);
            };
            style.styleSheet && (style.styleSheet.cssText += content) || style.appendChild(document.createTextNode(content));
        },
        _style: {},
    
    }

    效果:

     原理是,动态创建一个div,克隆输入框的所有样式,往div内动态添加两个span元素,span(text)里面装输入框里的文字,span(模仿光标),这两个元素都设置为行内块元素,然后只需要获取到span(模拟光标)在页面中的位置,就是光标所在的位置。

  • 相关阅读:
    程序员如何跨过自我推销的难关?
    常用接口分类与模块设计的方法
    如何设计分层架构和交互接口 API ?
    如何建立架构师的立体化思维?
    从程序员到架构师的技能图谱
    selenium鼠标、键盘操作常用API
    selenium元素定位之-css定位
    python每日一练之集合set
    selenium2简单的定位方法和Xpath定位
    python之元组
  • 原文地址:https://www.cnblogs.com/fqh123/p/13536522.html
Copyright © 2011-2022 走看看