JS 文字輸入框放大鏡效果

龍恩0707發表於2014-01-16

JS 文字輸入框放大鏡效果

      今天下午研究了下 "文字輸入框放大鏡效果" 當然KISSY官網也有這種元件 請看kissy demo

       其實這種效果 對於很多童鞋來說 應該並不陌生!我今年最早也是在 12306官網搶票 中 新增聯絡人 要填寫電話號碼中看到這種效果!如下圖所示:

      

      所以今天下午也就研究下這個,特此分享出來給大家!也做了一個簡單的DEMO jSFiddle連結地址如下:

     JSFiddle連結:

     想要檢視效果!請輕輕的點選我!

 基本原理:

     其實基本原理也很簡單!通過JS不斷的監聽輸入框值的變化(通過jquery中的keyup事件),有值的話 把內容值賦值給那顯示div上去。

配置引數如下:

   inputElem
'.inputElem',    輸入框目標元素
 parentCls  '.parentCls',     目標元素的父類
 align  'top',         對齊方式有 ['top','bottom','left','right']四種 預設為top
 splitType   [3,4,4],             拆分規則
delimiter  '-' ,             分隔符可自定義

 元件不足之處:

     1.不支援滑鼠右鍵 中的 複製 剪下 黏貼事件。目前只支援鍵盤操作。但是KISSY是支援的,因為KISSY有一個valueChange事件 可以不斷的監聽鍵盤操作(原理是:用個定時器不斷的檢測輸入框值得變化),滑鼠右鍵操作等等事件,也就是說可以實時的監聽輸入框之前值,之後值得變化,但是Jquery目前沒有這個事件。所以我目前只用keyup事件來做個demo。雖然網上有很多 關於 oninput && onpropertychange 實時監聽輸入框值的變化。但是我也試了下 在window7 IE下有問題 特別是IE9下 有嚴重的問題!就是不支援這個東西!所以也沒有用這個來監聽。至於KISSY中的 "valueChange"事件方法 我有空的時候 想偷下他們的程式碼 來改造下!呵呵!

程式碼分析:

 HTML程式碼:

<div class="parentCls">
    <input type="text" class="inputElem" autocomplete = "off" maxlength="11"/>
</div>

這樣的 父級class 取名為 "parentCls" (需要傳入,當然可以自己定義 如上配置項)。當前input預設取名為 "inputElem"(也可以自定義)。HTML結構就是這樣的。

現在來分析下JS程式碼:

1.  初始化,繫結事件:如下程式碼:

/**
      * 繫結事件
      * @method _bindEnv
      */
     _bindEnv: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;

        // 實時監聽輸入框值的變化
        $(_config.inputElem).each(function(index,item){

            $(item).keyup(function(e){
                var value = $.trim(e.target.value),
                    parent = $(this).closest(_config.parentCls);
                if(value == '') {
                    self._hide(parent);
                }else {

                    var html = $.trim($('.js-max-input',parent).html());

                    if(html != '') {
                        self._show(parent);
                    }
                }
                self._appendHTML($(this),value);
                self._position($(this));
            });
            
            $(item).unbind('focusin');
            $(item).bind('focusin',function(){
                var parent = $(this).closest(_config.parentCls),
                    html = $.trim($('.js-max-input',parent).html());

                if(html != '') {
                    self._show(parent);
                }
            });

            $(item).unbind('focusout');
            $(item).bind('focusout',function(){
                var parent = $(this).closest(_config.parentCls);
                self._hide(parent);
            });
        });
     },

     做了以下事件:1.不斷的用keyup監聽input值得變化。2. 動態的生成放大效果HTML程式碼。3.如果輸入框值為空 則隱藏掉放大效果div元素,否則 反之!4.就是對元素定位,目前支援四種定位 分別為top(頂部),bottom(底部),left(左側),right(右側),JSFiddle demo中做了三種定位(上,右,下)。左側一般不太可能。5.繫結點選焦點和失去焦點事件。(點選焦點顯示,失去焦點隱藏)等等。

2. 格式化一下顯示方式:程式碼如下:

/**
      * 格式化下
      * @method _formatStr
      */
     _formatStr: function(str){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var count = 0,
            output = [];
        for(var i = 0, ilen = _config.splitType.length; i < ilen; i++){
            var s = str.substr(count,_config.splitType[i]);
            if(s.length > 0){
                output.push(s);
            }
            count+= _config.splitType[i];
        }
        return output.join(_config.delimiter);
     },

比如我輸入 11122233344 且只能顯示11個數字的話 ,假如我用 "-"分隔符 拆分規則是:splitType:[3,4,4] .那麼顯示方式應該是:111-2223-3344 當然也可以用其他的分隔符顯示,上面的程式碼就做了這麼一件事件。基本的就這麼點!下面直接貼下程式碼吧!可以直接看程式碼 如果有不懂的地方可以留言 謝謝!

HTML程式碼:

<h2>輸入框放大鏡的demo</h2>
    <div style="height:50px;"></div>

    <div style="margin-left:56px; margin-top:6px;">我的方向是向上,允許輸入長度11位</div>
    <div class="parentCls">
        <input type="text" class="inputElem" autocomplete = "off" maxlength="11"/>
    </div>
    
    <div style="margin-left:56px; margin-top:6px;">我的方向是向右,允許輸入長度18位</div>
    <div class="parentCls">
        <input type="text" class="inputElem1" autocomplete = "off" maxlength="18"/>
    </div>
    
    <div style="margin-left:56px; margin-top:6px;">我的方向是向下,允許輸入長度18位</div>
    <div class="parentCls">
        <input type="text" class="inputElem2" autocomplete = "off" maxlength="18"/>
    </div>

CSS程式碼:

* {margin:0;padding:0;}
.parentCls {margin:5px 60px 0;}
 .js-max-input {border: solid 1px #ffd2b2;background: #fffae5;padding: 0 10px 0 10px;font-size:20px;color: #ff4400}

JS所有程式碼:

/**
 * JS 文字輸入框放大鏡效果
 * @author tugenhua
 * @time 2014-1-16
 */ 

 function TextMagnifier(options) {

     this.config = {
        
        inputElem          :     '.inputElem',     // 輸入框目標元素
        parentCls          :     '.parentCls',     // 目標元素的父類
        align              :     'top',            // 對齊方式有 ['top','bottom','left','right']四種 預設為top
        splitType          :     [3,4,4],          // 拆分規則
        delimiter          :     '-'                // 分隔符可自定義
     };

     this.cache = {
          isFlag  :  false
     };
     this.init(options);
 }

 TextMagnifier.prototype = {
     
     constructor: TextMagnifier,

     init: function(options) {
        this.config = $.extend(this.config,options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        
        self._bindEnv();
        
        
     },
     /*
      * 在body後動態新增HTML內容
      * @method _appendHTML
      */
     _appendHTML: function($this,value) {
         var self = this,
             _config = self.config,
             _cache = self.cache;

         var html = '',
             $parent = $($this).closest(_config.parentCls);

             if($('.js-max-input',$parent).length == 0) {
                html += '<div class="js-max-input"></div>';
                $($parent).append(html);
             }
             var value = self._formatStr(value);
             $('.js-max-input',$parent).html(value);
     },
     /*
      * 給目標元素定位
      * @method _position
      * @param target
      */
     _position: function(target){
        var self = this,
            _config = self.config;
        var elemWidth = $(target).outerWidth(),
            elemHeight = $(target).outerHeight(),
            elemParent = $(target).closest(_config.parentCls),
            containerHeight = $('.js-max-input',elemParent).outerHeight(); 
        
        $(elemParent).css({"position":'relative'});
        
        switch(true){
            
            case _config.align == 'top':
                
                $('.js-max-input',elemParent).css({'position':'absolute','top' :-elemHeight - containerHeight/2,'left':0});
                break;
            
            case _config.align == 'left':

                $('.js-max-input',elemParent).css({'position':'absolute','top' :0,'left':0});
                break;
            
            case _config.align == 'bottom':

                $('.js-max-input',elemParent).css({'position':'absolute','top' :elemHeight + 4 + 'px','left':0});
                break;
            
            case _config.align == 'right':

                $('.js-max-input',elemParent).css({'position':'absolute','top' :0,'left':elemWidth + 2 + 'px'});
                break;
        }
     },
     /**
      * 繫結事件
      * @method _bindEnv
      */
     _bindEnv: function(){
        var self = this,
            _config = self.config,
            _cache = self.cache;

        // 實時監聽輸入框值的變化
        $(_config.inputElem).each(function(index,item){

            $(item).keyup(function(e){
                var value = $.trim(e.target.value),
                    parent = $(this).closest(_config.parentCls);
                if(value == '') {
                    self._hide(parent);
                }else {

                    var html = $.trim($('.js-max-input',parent).html());

                    if(html != '') {
                        self._show(parent);
                    }
                }
                self._appendHTML($(this),value);
                self._position($(this));
            });
            
            $(item).unbind('focusin');
            $(item).bind('focusin',function(){
                var parent = $(this).closest(_config.parentCls),
                    html = $.trim($('.js-max-input',parent).html());

                if(html != '') {
                    self._show(parent);
                }
            });

            $(item).unbind('focusout');
            $(item).bind('focusout',function(){
                var parent = $(this).closest(_config.parentCls);
                self._hide(parent);
            });
        });
     },
     /**
      * 格式化下
      * @method _formatStr
      */
     _formatStr: function(str){
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var count = 0,
            output = [];
        for(var i = 0, ilen = _config.splitType.length; i < ilen; i++){
            var s = str.substr(count,_config.splitType[i]);
            if(s.length > 0){
                output.push(s);
            }
            count+= _config.splitType[i];
        }
        return output.join(_config.delimiter);
     },
     /*
      * 顯示 放大容器
      * @method _show
      */
     _show: function(parent) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        if(!_cache.isFlag) {
            $('.js-max-input',parent).show();
            _cache.isFlag = true;
        }
     },
     /*
      * 隱藏 放大容器
      * @method hide
      * {public}
      */
     _hide: function(parent) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        if(_cache.isFlag) {
            $('.js-max-input',parent).hide();
            _cache.isFlag = false;
        }
     }
 };
View Code

demo下載

相關文章