JS仿百度搜索自动提示框匹配查询功能


Posted in Javascript onNovember 21, 2013

1. 添加动态加载css文件 不需要引入css css全部在JS动态生成。
2. 不需要额外的标签 只需要一个input输入框 并且默认指定一个class类名为 "inputElem" 当然也可以自己配置参数 还需要一个当前父级容器增加一个默认类名 parentCls(也可以自己配置),因为输入框匹配值后需要一个隐藏域 所以需要隐藏域增加一个class "hiddenCls" 当然也支持自己配置参数。

如下代码:

<div class="parentCls">
        <div style="width:200px;height:26px;border:1px solid #ccc;">
            <input type="text" class="inputElem" style="width:200px;height:26px;line-height:26px;"/>
        </div>
        <input type="hidden" class="hiddenCls"/>
    </div>

    <div class="parentCls">
        <div style="width:200px;height:26px;border:1px solid #ccc;">
            <input type="text" class="inputElem" style="width:200px;height:26px;line-height:26px;"/>
        </div>
        <input type="hidden" class="hiddenCls"/>
    </div>

3. 支持页面上有多个输入框。

4. 支持鼠标点击和 键盘 上移和下移键操作 类似于百度输入框。
页面上所有的标签都是动态的生成的,不需要额外的标签。如上面的 只需要input标签 其他的div标签不依赖 只需要父级元素增加class "parentCls"(当然可以自己配置类名),
及要传给后台开发人员的隐藏域输入框 增加一个class "hiddenCls" 当然也可以自动配置参数。

我的模糊查询匹配的需求是这样的:
1. 每keyup时候 点击或者键盘上移下移操作 输入框填充用户名/工号 隐藏域填充工号 发请求 服务器返回数据 渲染出来。当然 隐藏域填充工号 值是form表单提交时候 后台要拿到提交过来的工号 所以需要这么一个隐藏域。
2. 当用户直接在输入框输入值时候 并没有键盘上移下移 或者 点击下拉框某一项时候 当鼠标失去焦点时候(blur) 当前输入框值为空 隐藏域值为空,这样做的目的 是为了防止上次form提交过后的数据仍然保存在隐藏域里面 当用户重新输入的时候 用户也并没有操作键盘上下移操作或者点击操作 再点击提交按钮时(失去焦点),那么值为空 隐藏域值为空 这样防止搜索出来不是用户输入的那个东东。
3. 当用户点击某一项时候 或者 上移下移时候 输入框动态的生成值 且输入框值现在不能重新输入 只有当点击输入框x的时候 才可以重新输入。
4. 已经遗留输入框可以多选的接口 目前还未完善输入框多选的操作。
5. 禁止ctrl+v 或者右键 粘贴操作。

下面HTML代码如下:

<div class="parentCls">
        <div style="width:200px;height:26px;border:1px solid #ccc;">
            <input type="text" class="inputElem" style="width:200px;height:26px;line-height:26px;"/>
        </div>
        <input type="hidden" class="hiddenCls"/>
    </div>

    <div class="parentCls">
        <div style="width:200px;height:26px;border:1px solid #ccc;">
            <input type="text" class="inputElem" style="width:200px;height:26px;line-height:26px;"/>
        </div>
        <input type="hidden" class="hiddenCls"/>
    </div>
    <input type="button" value="提交"/>

JS代码如下:

/**
 * JS 模糊查询
 * @author tugenhua
 * @date 2013-11-19
 * @param 1.当前的input add targetCls 
 * 2. 隐藏域里面统一增加同类名 叫 hiddenCls
 * 3. 在各个父级元素上 添加类名 parentCls
 */
 function AutoComplete (options) {
     this.config = {
        targetCls          : '.inputElem',          // 输入框目标元素
        parentCls          : '.parentCls',          // 父级类
        hiddenCls          : '.hiddenCls',          // 隐藏域input
        searchForm         :'.jqtransformdone',     //form表单
        hoverBg            : 'hoverBg',             // 鼠标移上去的背景
        outBg              : 'outBg',               // 鼠标移下拉的背景
        isSelectHide       : true,                 // 点击下拉框 是否隐藏
        url                : '',                    // url接口
        height             : 0,                     // 默认为0 不设置的话 那么高度自适应
        manySelect         : false,                 // 输入框是否多选 默认false 单选
        renderHTMLCallback : null,                  // keyup时 渲染数据后的回调函数
        callback           : null,                  // 点击某一项 提供回调
        closedCallback     : null                   // 点击输入框某一项x按钮时 回调函数
     };
     this.cache = {
        currentIndex        : -1,
        oldIndex            : -1,
        inputArrs           : []                 // 多选时候 输入框值放到数组里面去
     };
     this.init(options);
 }
 AutoComplete.prototype = {
    constructor: AutoComplete,
    init: function(options) {
        this.config = $.extend(this.config, options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
         // 鼠标点击输入框时候 
          $(_config.targetCls).each(function(index,item) {
              /*
               *  禁止 ctrl+v 和 黏贴事件
               */
              $(item).unbind('paste');
              $(item).bind('paste',function(e){
                  e.preventDefault();
                  var target = e.target,
                      targetParent = $(target).closest(_config.parentCls);
                  $(this).val('');
                  $(_config.hiddenCls,targetParent) && $(_config.hiddenCls,targetParent).val('');
              });
              $(item).keyup(function(e){
                  _cache.inputArrs = [];
                  var targetVal = $.trim($(this).val()),
                      keyCode = e.keyCode,
                      elemHeight = $(this).outerHeight(),
                      elemWidth = $(this).outerWidth();
                  // 如果输入框值为空的话 那么隐藏域的value清空掉
                  if(targetVal == '') {
                       var curParents = $(this).closest(_config.parentCls);
                       $(_config.hiddenCls,curParents).val('');
                  }
                  var targetParent = $(this).parent();
                  $(targetParent).css({'position':'relative'});
                  if($('.auto-tips',targetParent).length == 0) {
                      // 初始化时候 动态创建下拉框容器
                     $(targetParent).append($('<div class="auto-tips hidden"></div>'));
                     $('.auto-tips',targetParent).css({'position':'absolute','top':elemHeight,'left':'0px','z-index':999,'width':elemWidth,'border':'1px solid #ccc'});
                  }
                  
                  var curIndex = self._keyCode(keyCode);
                  if(curIndex > -1){
                          self._keyUpAndDown(targetVal,e,targetParent);
                    }else {
                         if(targetVal != '') {
                            self._doPostAction(targetVal,targetParent);
                         }
                    }
              });
              // 失去焦点时 如果没有点击 或者上下移时候 直接输入 那么当前输入框值情况 隐藏域值情况
              $(item).blur(function(e){
                  var target = e.target,
                      targetParent = $(target).closest(_config.parentCls);
                  if($(this).attr('up') || $(this).attr('down')) {
                     return;
                  }else {
                     $(this).val('');
                     $(_config.hiddenCls,targetParent).val('');
                  }
              });
          });
          // 阻止form表单默认enter键提交
          $(_config.searchForm).each(function(index,item) {
               $(item).keydown(function(e){
                    var keyCode = e.keyCode;
                    if(keyCode == 13) {
                        return false;
                    }
               });
          });
          // 点击文档
          $(document).click(function(e){
             e.stopPropagation();
             var target = e.target,
                 tagParent = $(target).parent(),
                 attr = $(target,tagParent).closest('.auto-tips');
             var tagCls = _config.targetCls.replace(/^\./,'');
             if(attr.length > 0 || $(target,tagParent).hasClass(tagCls)) {
                return;
             }else {
                $('.auto-tips').each(function(index,item){
                    !$(item,tagParent).hasClass('hidden') && $(item,tagParent).addClass('hidden');
                });
             }
          });
          var stylesheet = '.auto-tips { margin: 0 1px; list-style: none;height:auto !important;padding: 0px;position:absolute; border:1px solid #ccc; top:27px; left:0; z-index:999; width:100%;background:#fff !important;}' + 
                           '.auto-tips p {overflow: hidden;margin: 1px 0;padding: 5px 5px;border-bottom: 1px solid #e7e7e7;color: #666;text-decoration: none;line-height: 23px;white-space: nowrap;cursor: pointer;zoom: 1;}' + 
                           '.auto-tips p img{ vertical-align:middle;float:left;}' + 
                           '.create-input{line-height:26px,padding-left:3px;}' + 
                           '.create-input span{margin-top:1px;height:24px;float:left;}' +
                           '.create-input span i,.auto-tips span a{font-style:normal;float:left;cursor:default;}' +
                           '.create-input span a{padding:0 8px 0 3px;cursor:pointer;}' +
                           '.auto-tips p.hoverBg {background-color: #669cb6;color: #fff;cursor: pointer;}' + 
                           '.hidden {display:none;}';
          this._addStyleSheet(stylesheet);
    },
    /**
     * 键盘上下键操作
     */
    _keyUpAndDown: function(targetVal,e,targetParent) {
        var self = this,
            _cache = self.cache,
            _config = self.config;
        // 如果请求成功后 返回了数据(根据元素的长度来判断) 执行以下操作
        if($('.auto-tips p',targetParent) && $('.auto-tips p',targetParent).length > 0) {
            var plen = $('.auto-tips p',targetParent).length,
                keyCode = e.keyCode;
                _cache.oldIndex = _cache.currentIndex;
            // 上移操作
            if(keyCode == 38) {
                if(_cache.currentIndex == -1) {
                    _cache.currentIndex = plen - 1;
                }else {
                    _cache.currentIndex = _cache.currentIndex - 1;
                    if(_cache.currentIndex < 0) {
                        _cache.currentIndex = plen - 1;
                    }
                }
                if(_cache.currentIndex !== -1) {
                    !$('.auto-tips .p-index'+_cache.currentIndex,targetParent).hasClass(_config.hoverBg) &&
                    $('.auto-tips .p-index'+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                    var curAttr = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('data-html'),
                        embId = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('embId');
                    // 判断是否是多选操作 多选操作 暂留接口
                    if(_config.manySelect) {
                        _cache.inputArrs.push(curAttr);
                        _cache.inputArrs = self._unique(_cache.inputArrs);
                        self._manySelect(targetParent);
                    }else {
                        $(_config.targetCls,targetParent).val(curAttr);
                        // 上移操作增加一个属性 当失去焦点时候 判断有没有这个属性
                        if(!$(_config.targetCls,targetParent).attr('up')){
                            $(_config.targetCls,targetParent).attr('up','true');
                        }
                        
                        var pCls = $(_config.targetCls,targetParent).closest(_config.parentCls);
                        $(_config.hiddenCls,pCls).val(embId);
                        self._createDiv(targetParent,curAttr);
                        self._closed(targetParent);
                        // hover
                        self._hover(targetParent);
                    }
                }
            }else if(keyCode == 40) { //下移操作
                if(_cache.currentIndex == plen - 1) {
                    _cache.currentIndex = 0;
                }else {
                    _cache.currentIndex++;
                    if(_cache.currentIndex > plen - 1) {
                        _cache.currentIndex = 0;
                    }
                }
                if(_cache.currentIndex !== -1) {
                    !$('.auto-tips .p-index'+_cache.currentIndex,targetParent).hasClass(_config.hoverBg) &&
                    $('.auto-tips .p-index'+_cache.currentIndex,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                    var curAttr = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('data-html'),
                        embId = $('.auto-tips .p-index'+_cache.currentIndex,targetParent).attr('embId');
                    
                    // 判断是否是多选操作 多选操作 暂留接口
                    if(_config.manySelect) {
                        _cache.inputArrs.push(curAttr);
                        _cache.inputArrs = self._unique(_cache.inputArrs);
                        self._manySelect(targetParent);
                    }else {
                        $(_config.targetCls,targetParent).val(curAttr);
                        // 下移操作增加一个属性 当失去焦点时候 判断有没有这个属性
                        if(!$(_config.targetCls,targetParent).attr('down')){
                            $(_config.targetCls,targetParent).attr('down','true');
                        }
                        var pCls = $(_config.targetCls,targetParent).closest(_config.parentCls);
                        $(_config.hiddenCls,pCls).val(embId);
                        self._createDiv(targetParent,curAttr);
                        self._closed(targetParent);
                        // hover
                        self._hover(targetParent);
                    }
                }
            }else if(keyCode == 13) { //回车操作
                var curVal = $('.auto-tips .p-index'+_cache.oldIndex,targetParent).attr('data-html');
                $(_config.targetCls,targetParent).val(curVal);
                if(_config.isSelectHide) {
                    !$(".auto-tips",targetParent).hasClass('hidden') && $(".auto-tips",targetParent).addClass('hidden');
                }
                _cache.currentIndex = -1;
                _cache.oldIndex = -1;
            }
        }
    },
    // 键码判断
    _keyCode: function(code) {
        var arrs = ['17','18','38','40','37','39','33','34','35','46','36','13','45','44','145','19','20','9'];
        for(var i = 0, ilen = arrs.length; i < ilen; i++) {
            if(code == arrs[i]) {
                return i;
            }
        }
        return -1;
    },
    _doPostAction: function(targetVal,targetParent) {
        var  self = this,
             _cache = self.cache,
             _config = self.config,
             url = _config.url;
        // 假如返回的数据如下:
        var results = [{lastName:'tugenhua',emplId:'E0987',image:''},{lastName:'tugenhua',emplId:'E0988',image:''},{lastName:'tugenhua',emplId:'E0989',image:''}];
        self._renderHTML(results,targetParent);
        self._executeClick(results,targetParent);
       /** $.get(url+"?keyword="+targetVal+"×tamp="+new Date().getTime(),function(data){
            var ret = $.parseJSON(data.content),
                results = ret.results;
            if(results.length > 0) {
                self._renderHTML(results,targetParent);
                self._executeClick(results,targetParent);
            }else {
                !$('.auto-tips',targetParent).hasClass('hidden') && $('.auto-tips',targetParent).addClass("hidden");
                $('.auto-tips',targetParent).html('');
            }
        });**/
    },
    _renderHTML: function(ret,targetParent) {
        var self = this,
            _config = self.config,
            _cache = self.cache,
            html = '';
        for(var i = 0, ilen = ret.length; i < ilen; i+=1) {
            html += '<p  data-html = "'+ret[i].lastName+'('+ret[i].emplId+')" embId="'+ret[i].emplId+'" class="p-index'+i+'">' + 
                       '<img src="'+ret[i].image+'" style="margin-right:5px;" height="25" width="25" title="" alt="">' + 
                       '<span>'+ret[i].lastName+'('+ret[i].emplId+')</span>' + 
                    '</p>';
        }
        // 渲染值到下拉框里面去
        $('.auto-tips',targetParent).html(html);
         $('.auto-tips',targetParent).hasClass('hidden') && $('.auto-tips',targetParent).removeClass('hidden');
        $('.auto-tips p:last',targetParent).css({"border-bottom":'none'});
        _config.renderHTMLCallback && $.isFunction(_config.renderHTMLCallback) && _config.renderHTMLCallback();
        // 出现滚动条 计算p的长度 * 一项p的高度 是否大于 设置的高度 如是的话 出现滚动条 反之
        var plen = $('.auto-tips p',targetParent).length,
            pheight = $('.auto-tips p',targetParent).height();
        if(_config.height > 0) {
            if(plen*pheight > _config.height) {
                $('.auto-tips',targetParent).css({'height':_config.height,'overflow':'auto'});
            }else {
                $('.auto-tips',targetParent).css({'height':'auto','overflow':'auto'});
            }
        }
    },
    /**
      * 当数据相同的时 点击对应的项时 返回数据
      */
    _executeClick: function(ret,targetParent) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
         $('.auto-tips p',targetParent).unbind('click');
         $('.auto-tips p',targetParent).bind('click',function(e){
              var dataAttr = $(this).attr('data-html'),
                  embId = $(this).attr('embId');
              // 判断是否多选
              if(_config.manySelect) {
                  _cache.inputArrs.push(dataAttr);
                  _cache.inputArrs = self._unique(_cache.inputArrs);
                  self._manySelect(targetParent);
              }else {
                 $(_config.targetCls,targetParent).val(dataAttr);
                 var parentCls = $(_config.targetCls,targetParent).closest(_config.parentCls),
                     hiddenCls = $(_config.hiddenCls,parentCls);
                 $(hiddenCls).val(embId);
                 self._createDiv(targetParent,dataAttr);
                 // hover
                 self._hover(targetParent);
                 !$(_config.targetCls,targetParent).hasClass('hidden') && $(_config.targetCls,targetParent).addClass('hidden');
              }
              self._closed(targetParent);
              if(_config.isSelectHide) {
                  !$('.auto-tips',targetParent).hasClass('hidden') && $('.auto-tips',targetParent).addClass('hidden');
              }
              _config.callback && $.isFunction(_config.callback) && _config.callback();
         });
         // 鼠标移上效果
         $('.auto-tips p',targetParent).hover(function(e){
             !$(this,targetParent).hasClass(_config.hoverBg) &&
             $(this,targetParent).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
         });
    },
    _hover: function(targetParent){
        $('.create-input span',targetParent).hover(function(){
            $(this).css({"background":'#ccc','padding-left':'0px'}); 
        },function(){
             $(this).css({"background":''});
        });
    },
    // 动态的创建div标签 遮住input输入框
    _createDiv: function(targetParent,dataAttr){
         var self = this,
             _config = self.config;
         var iscreate = $('.create-input',targetParent);
         // 确保只创建一次div
         if(iscreate.length > 0) {
            $('.create-input',targetParent).remove();
         }
         $(targetParent).prepend($('<div class="create-input"><span><i></i></span></div>'));
         $('.create-input span i',targetParent).html(dataAttr);
         $(_config.targetCls,targetParent).val(dataAttr);
         $('.create-input span',targetParent).append('<a class="alink">X</a>');
         $('.alink',targetParent).css({'float':'left','background':'none'});
    },
    // X 关闭事件
    _closed: function(targetParent){
         var self = this,
             _config = self.config;
         /*
          * 点击X 关闭按钮
          * 判断当前输入框有没有up和down属性 有的话 删除掉 否则 什么都不做
          */
          $('.alink',targetParent).click(function(){
             $('.create-input',targetParent) && $('.create-input',targetParent).remove();
             $(_config.targetCls,targetParent) && $(_config.targetCls,targetParent).hasClass('hidden') &&
             $(_config.targetCls,targetParent).removeClass('hidden');
             $(_config.targetCls,targetParent).val('');
             //清空隐藏域的值
             var curParent = $(_config.targetCls,targetParent).closest(_config.parentCls);
             $(_config.hiddenCls,curParent).val('');
             var targetInput = $(_config.targetCls,targetParent);
             if($(targetInput).attr('up') || $(targetInput).attr('down')) {
                 $(targetInput).attr('up') && $(targetInput).removeAttr('up');
                 $(targetInput).attr('down') && $(targetInput).removeAttr('down');
             }
             _config.closedCallback && $.isFunction(_config.closedCallback) && _config.closedCallback();
          });
    },
    /*
     * 数组去重复
     */
    _unique: function(arrs) {
        var obj = {},
            newArrs = [];
        for(var i = 0, ilen = arrs.length; i < ilen; i++) {
            if(obj[arrs[i]] != 1) {
                newArrs.push(arrs[i]);
                obj[arrs[i]] = 1;
            }
        }
        return newArrs;
    },
    /*
     * 输入框多选操作
     */
    _manySelect: function(targetParent) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        if(_cache.inputArrs.length > 0) {
            $(_config.targetCls,targetParent).val(_cache.inputArrs.join(','));
        }
    },
    /*
     * 判断是否是string
     */
     _isString: function(str) {
        return Object.prototype.toString.apply(str) === '[object String]';
     },
    /*
     * JS 动态添加css样式
     */
    _addStyleSheet: function(refWin, cssText, id){
        var self = this;
        if(self._isString(refWin)) {
            id = cssText;
            cssText = refWin;
            refWin = window;
        }
        refWin = $(refWin);
        var doc = document;
        var elem;
        if (id && (id = id.replace('#', ''))) {
            elem = $('#' + id, doc);
        }
        // 仅添加一次,不重复添加
        if (elem) {
            return;
        }
       //elem = $('<style></style>'); 不能这样创建 IE8有bug
        elem =  document.createElement("style");
        // 先添加到 DOM 树中,再给 cssText 赋值,否则 css hack 会失效
        $('head', doc).append(elem);
        if (elem.styleSheet) { // IE
            elem.styleSheet.cssText = cssText;
        } else { // W3C
            elem.appendChild(doc.createTextNode(cssText));
        }
    },
    /*
     * 销毁操作 释放内存
     */
    destory: function() {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        _cache.ret  = [];
        _cache.currentIndex = 0;
        _cache.oldIndex = 0;
        _cache.inputArrs = [];
        _config.targetCls = null;
    }
 };
 // 初始化
 $(function(){
    var auto = new AutoComplete({
       // url: '/rocky/commonservice/user/find.json'
    }); 
 });
Javascript 相关文章推荐
JQuery 表单中textarea字数限制实现代码
Dec 07 Javascript
PHP abstract与interface之间的区别
Nov 11 Javascript
Extjs grid添加一个图片状态或者按钮的方法
Apr 03 Javascript
jquery使用$(element).is()来判断获取的tagName
Aug 24 Javascript
jquery实现通用的内容渐显Tab选项卡效果
Sep 07 Javascript
AngularJS 中的Promise --- $q服务详解
Sep 14 Javascript
JS获取鼠标相对位置的方法
Sep 20 Javascript
JS鼠标滚动分页效果示例
Jul 05 Javascript
vue移动端UI框架实现QQ侧边菜单组件
Mar 09 Javascript
Vue+Element实现动态生成新表单并添加验证功能
May 23 Javascript
js实现百度淘宝搜索功能
Feb 17 Javascript
Jquery 获取相同NAME 或者id删除行操作
Aug 24 jQuery
探讨javascript是不是面向对象的语言
Nov 21 #Javascript
JS中把字符转成ASCII值的函数示例代码
Nov 21 #Javascript
Javascript对象属性方法汇总
Nov 21 #Javascript
获得Javascript对象属性个数的示例代码
Nov 21 #Javascript
XMLHttpRequest处理xml格式的返回数据(示例代码)
Nov 21 #Javascript
浅析JavaScript中的常用算法与函数
Nov 21 #Javascript
非常漂亮的JS+CSS图片幻灯切换特效
Nov 20 #Javascript
You might like
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
浅析PHP程序防止ddos,dns,集群服务器攻击的解决办法
2013/06/18 PHP
PHP请求Socket接口测试实例
2016/08/12 PHP
php添加数据到xml文件的简单例子
2016/09/08 PHP
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
js页面跳转的常用方法整理
2013/10/18 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
Jquery选择器中使用变量实现动态选择例子
2014/07/25 Javascript
Javascript核心读书有感之词法结构
2015/02/01 Javascript
jQuery提示插件qTip2用法分析(支持ajax及多种样式)
2016/06/08 Javascript
jQuery如何解决IE输入框不能输入的问题
2016/10/08 Javascript
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
2016/12/15 Javascript
jQuery实现的简单在线计算器功能
2017/05/11 jQuery
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
基于VuePress 轻量级静态网站生成器的实现方法
2018/04/17 Javascript
Vue-Quill-Editor富文本编辑器的使用教程
2018/09/21 Javascript
详解微信小程序scroll-view横向滚动的实践踩坑及隐藏其滚动条的实现
2019/03/14 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
Vue防止白屏添加首屏动画的实例
2019/10/31 Javascript
vue axios请求成功却进入catch的原因分析
2020/09/08 Javascript
[07:54]DOTA2-DPC中国联赛 正赛 iG vs VG 选手采访
2021/03/11 DOTA
python中的一些类型转换函数小结
2013/02/10 Python
在Python中使用itertools模块中的组合函数的教程
2015/04/13 Python
python做量化投资系列之比特币初始配置
2018/01/23 Python
pyqt5的QWebEngineView 使用模板的方法
2018/08/18 Python
python实现微信小程序自动回复
2018/09/10 Python
详解Python给照片换底色(蓝底换红底)
2019/03/22 Python
python Shapely使用指南详解
2020/02/18 Python
python和node.js生成当前时间戳的示例
2020/09/29 Python
医学生自荐信
2013/12/03 职场文书
高校辅导员推荐信范文
2013/12/25 职场文书
村长党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
一个都不能少观后感
2015/06/04 职场文书
CSS3实现的3D隧道效果
2021/04/27 HTML / CSS
MySQL完整性约束的定义与实例教程
2021/05/30 MySQL