2014.01.11 笔记

文本框智能提示功能的 jQuery 插件 《jQuery.suggest.js》

 

 jQuery.suggest 是一个提供文本框智能提示功能的 jQuery 插件,当在文本框中输入字符时,与此相关的内容会以浅灰色显示在文本框中。提示内容可使用键盘上下选择,按下回车后即可自动输入。可自定义提示文字的 CSS 样式。

 使用时,需要引用这两个JS文件。

<script src="jquery.js"></script>
<script src="jquery.suggest.js"></script>

调用时:

<input type="text" name="search" id="search" />

$(function () {
  $('#test').suggest([source],[options]);
});

以下是jquery.suggest.js 的源码:

(function($) {

  $.fn.suggest = function(source, options) {
    
    var settings = $.extend({
      suggestionColor       : '#ccc',
      moreIndicatorClass    : 'suggest-more'
    }, options);

    return this.each(function() {

      $this = $(this);
      
      // 该对象将设置提示显示和设置输入文字匹配的样式
      var $suggest = $('<div/>', {
        'css' : {
          'position'        : 'absolute',//生成绝对定位的元素
          'height'          : $this.height(),
          'width'           : $this.width(),
          'top'             : $this.css('borderTopWidth'),
          'left'            : $this.css('borderLeftWidth'),
          'padding'         : $this.cssShortForAllSides('padding'),
          'margin'          : $this.cssShortForAllSides('margin'),
          'fontFamily'      : $this.css('fontFamily'),
          'fontSize'        : $this.css('fontSize'),
          'fontStyle'       : $this.css('fontStyle'),
          'lineHeight'      : $this.css('lineHeight'),
          'fontWeight'      : $this.css('fontWeight'),
          'letterSpacing'   : $this.css('letterSpacing'),
          'backgroundColor' : $this.css('backgroundColor'),
          'color'           : settings.suggestionColor
        }
      });
      
      var $more = $('<span/>', {
        'css' : {
          'position'        : 'absolute',
          'top'             : $suggest.height() + parseInt($this.css('fontSize'), 10) / 2,
          'left'            : $suggest.width(),
          'display'         : 'block',
          'fontSize'        : $this.css('fontSize'),
          'fontFamily'      : $this.css('fontFamily'),
          'color'           : settings.suggestionColor
        },
        'class'             : settings.moreIndicatorClass
      })
      .html('&hellip;')//&hellip; 表示省略号
      .hide();

      $this
        .attr({
          'autocomplete'    : "off",//on :让浏览器自动记录之前输入的值;off 则反之
          'spellcheck'      : "false",//HTML5 支持的属性,用true和false来设定是否对用户输入的文章内容进行拼写检查。
          'dir'             : "ltr" //dir 标签定义目录列表
        })
              
        .css({
          'background'      : 'transparent' // 设置背景透明,显示提示选项  
        })                  
        .wrap($('<div/>', {
          'css': { 
            'position'      : 'relative',//生成相对定位的元素,相对于其正常位置进行定位
            'paddingBottom' : '1em'
          }
        }))//wrap: 在每个匹配的元素外层包上一个div
        
        .bind('keydown.suggest', function(e){
          var code = (e.keyCode ? e.keyCode : e.which);
          
          //若 按下Tab键,并且没有按下Alt键
          if (code == 9 && !e.altKey) {
            e.preventDefault();//阻止元素发生默认的行为

          } else if (code == 13) {
            if (!$suggest.is(':empty')) {
              //按回车时,如果输入框为空,阻止回车事件的发生
              e.preventDefault();
            }
          
          } else if (code == 38 || code == 40) {
            //按方向键时
            e.preventDefault();
            //定义一个变量装载下拉选项值
            var suggestions = $(this).data('suggestions');
            
            if (suggestions.all.length > 1) {
              // 若有数据
              //当按向下方向键时,若当前所选的项不是最后一项,则设置下一项被选中
              if (code == 40 && suggestions.index < suggestions.all.length - 1) {
                suggestions.suggest.html(suggestions.all[++suggestions.index]);
              
              } 
              //当按向上方向键时,如果当前所选项不是第一项,则上一项被选中
              else if (code == 38 && suggestions.index > 0) {
                suggestions.suggest.html(suggestions.all[--suggestions.index]);
              }
              $(this).data('suggestions').index = suggestions.index;
            }
          }
        })
        
        .bind('keyup.suggest', function(e) {
          var code = (e.keyCode ? e.keyCode : e.which);
          
          if (code == 38 || code == 40) {
            return false;
          }
          
          $more.hide();
          
          var needle = $(this).val();
          
          var needleWithWhiteSpace = needle.replace(' ', '&nbsp;');       
          
          if (code == 9 || code == 13) {
            //当按下Tab键或者是回车键时,若提示框中有值
            if ($suggest.text().length > 0) {
              e.preventDefault();//禁止其默认事件发生
              var suggestions = $(this).data('suggestions');
              $(this).val(suggestions.terms[suggestions.index]);
              
              $suggest.empty();//提示信息隐藏
              return false;
            }
          }
          
          // 清空提示
          $suggest.empty();
        
          if (!$.trim(needle).length) {
            return false;
          }
          
          
          //文本框中已输入的值,若跟数据源中某值相匹配,则terms[]添加: 
          var regex = new RegExp('^' + needle.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'i');
          var suggestions = [], terms = [];
          for (var i = 0, l = source; i < l.length; i++) {
            if (regex.test(l[i])) {      
              terms.push(l[i]);
              suggestions.push(needleWithWhiteSpace + l[i].slice(needle.length));//slice():已有的数组中返回选定的元素
            }
          }
          if (suggestions.length > 0) {

            if (suggestions[0] !== needle) {
              $suggest.html(suggestions[0]);
            }

            $(this).data('suggestions', {
              'all'    : suggestions,
              'terms'  : terms,
              'index'  : 0,
              'suggest': $suggest
            });
            

            if (suggestions.length > 1) {
              $more.show();
            }
          }
        })
    

        .bind('blur.suggest', function(){
          $suggest.empty();
        });
        
        
        $suggest.insertAfter($this);
        $more.insertAfter($suggest);
        
    });

  };
  
  /* A little helper to calculate the sum of different
   * CSS properties around all four sides
   *
   * EXAMPLE:
   * $('#my-div').cssSum('padding');
   */
  $.fn.cssShortForAllSides = function(property) {
    var $self = $(this), sum = [];
    var properties = $.map(['Top', 'Right', 'Bottom', 'Left'], function(side){
      return property + side;
    });
    $.each(properties, function(i, e) {
      sum.push($self.css(e) || "0");
    });
    return sum.join(' ');
  };
})(jQuery);

 

 代码中学习到的JS方法有:

1.  $.attr({
          'autocomplete'    : "off",//on :让浏览器自动记录之前输入的值;off 则反之
          'spellcheck'      : "false",//HTML5 支持的属性,用true和false来设定是否对用户输入的文章内容进行拼写检查。
          'dir'             : "ltr" //dir 标签定义目录列表(这点还不太清楚是干嘛的)
        }) // 这些之前没有用过

   

2. event.preventDefault();//如果调用此方法,默认事件行为将不会被触发。  (若某a标签的点击事件中,调用此方法,点击此a标签将不能跳转到链接。)

3.  for (var i = 0, l = source; i < l.length; i++){}   //不太清楚这样写有什么好处,之前没有看到过这种写法,若是我写,肯定是把l=source 这句定义在了 for循环外面。

4.  //slice():已有的数组中返回选定的元素
       var arry=[a,b,c,d,e,f,g];
       var arryStr= arry.slice(2,4);
         arrystr: "c,d,e"  
       var arryStr2=arry.slice(3); 
         arrystr2:"d,e,f,g"

5.  $("#div1").data('suggestions', {
              'name' : "abc",
              'sex'  : 0,
              'age'  : 22,
              'qq': "2455555"
            });
    //之前只是知道.data(key,value) 的方法,没有用过。 今天突然意思到:在匹配元素上存储任意相关数据 或 返回匹配的元素集合中的第一个元素的给定名称的数据存储的值,
    // 这里为什么要加:匹配元素?  然后仔细看了一下,原来不是我以为的。 它是用来:在DOM元素上设置不同的数据值。    但是还是不太清楚这个用在何处。。。。
上面的方法执行后,可以如此调用:

var a=$("#div1").data('suggestions');//a=object{name:"abc",sex:0,age:22,qq:2455555}
var b=$("#div1").data('suggestions').name;//b="abc"



例2: 这是Html5 中的 data属性。
<div id="div1" data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div> $("#div1").data("role");// "page" $("#div1").data("lastValue");// 43 $("#div1").data("hidden");// true $("#div1").data("options").name;// "John" -------------------------------- 还有一种是: jQuery.data(element, key, value ); 这种写法等同于:$(element).date(key,value);

 

 

posted @ 2014-01-11 20:55  aspnet_如月  阅读(253)  评论(1编辑  收藏  举报