• 一个简单的输入关键字添加标签效果


    效果

    访问:https://bxcn.github.io/keyWord/

    目录结构

    参考

    https://github.com/bxcn/keyWord

    readme.md

    一个简单的输入关键字添加标签效果 
      
     实现功能: 
      输入关键字加空格键添加tag标签 
     按Backspace键删除一个标签 
     输入关键字后,鼠标失去焦点添加tag标签 
     keyWord.init方法初始化方法 
     防止输入重复的关键字 
     限止最多输入几个关键字 
     
     
    <style>
        .block {
            display:flex;
            flex-direction:row;
            align-items:center;
            500px;
            height:30px;
            border:1px solid #ddd;
            padding:10px;
            margin:100px auto 0;
        }
        #wordTags {
            display:flex;
            flex-wrap:nowrap;
        }
        input{
            100%;
            height:20px;
            border:none;
        }
    </style>
    
    <div class="block">
        <div id="wordTags"></div>
        <input id="wordInput" type="text" name="" placeholder="请输入关键词以空格结尾">
        <input id="wordHiddenInput" type="hidden" name="">
    </div>
    
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
    <script type="text/javascript" src="aspect.js"></script>
    <script type="text/javascript" src="keyWord.js"></script>
     
     $(function () {
        var keyWord = $("#wordInput").keyWord({
            panel: '#wordTags',
            value: '#wordHiddenInput',
            max: 3,
            tips: '最多只能输入3项'
        });
    
        keyWord.init('php,java,前端开发')
    });
    
     
     属性说明: 
      panel:面板的id 
     value:隐藏字段的id 
     max:最多输入关键字个数 
     tips:提示语 
     

    index.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>keyWord--一个简单的输入关键字添加标签效果</title>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="index.css">
    </head>
    <body>
        <style>
            .block {
                display:flex;
                flex-direction:row;
                align-items:center;
                500px;
                height:30px;
                border:1px solid #ddd;
                padding:10px;
                margin:100px auto 0;
            }
            #wordTags {
                display:flex;
                flex-wrap:nowrap;
            }
            input{
                100%;
                height:20px;
                border:none;
            }
        </style>
    </body>
    <div class="block">
        <div id="wordTags"></div>
        <input id="wordInput" type="text" name="" placeholder="请输入关键词以空格结尾">
        <input id="wordHiddenInput" type="hidden" name="">
    </div>
    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.js"></script>
    <script type="text/javascript" src="aspect.js"></script>
    <script type="text/javascript" src="keyWord.js"></script>
    <script type="text/javascript">
    
    $(function () {
        var keyWord = $("#wordInput").keyWord({
            panel: '#wordTags',
            value: '#wordHiddenInput',
            max: 3,
            tips: '最多只能输入3项'
        });
    
        keyWord.init('php,php,java,前端开发')
    });
    
    </script>
    </html>

    index.css

    @charset "UTF-8";
    @font-face { font-family: 'iconfont'; src: url("../fonts/iconfont.eot");  /* IE9*/ src: url("../fonts/iconfont.eot?#iefix") format("embedded-opentype"), url("../fonts/iconfont.woff") format("woff"), url("../fonts/iconfont.ttf") format("truetype"), url("../fonts/iconfont.svg#iconfont") format("svg");  /* iOS 4.1- */ }
    html { position: relative; min-height: 100%; -webkit-overflow-scrolling: touch; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
    article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, body, div, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, fieldset, legend, button, input, textarea, form, th, td { margin: 0; padding: 0; vertical-align: baseline; }
    article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary { display: block; }
    audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
    body, button, input, select, textarea { outline: none; }
    h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: normal; }
    address, cite, dfn, em, var, i { font-style: normal; }
    body {  line-height: 120%; font-size: 14px; color: #4d4d4d; font-family: Arial,  sans-serif;}
    small { font-size: 80%; }
    ul, ol { list-style: none outside none; }
    a { text-decoration: none; }
    a:hover { text-decoration: none; outline: 0; }
    a:active { text-decoration: none; outline: 0; }
    a:focus { text-decoration: none; outline: 0; }
    abbr[title], acronym[title] { border-bottom: 1px dotted; cursor: help; }
    q:before, q:after { content: ''; }
    mark { background-color: #ff0; color: #000; }
    pre {  /**
        normal  默认。空白会被浏览器忽略。
        pre     空白会被浏览器保留。其行为方式类似 HTML 中的 <pre> 标签。
        nowrap  文本不会换行,文本会在在同一行上继续,直到遇到 <br> 标签为止。
        pre-wrap  保留空白符序列,但是正常地进行换行。
        pre-line  合并空白符序列,但是保留换行符。
        inherit 规定应该从父元素继承 white-space 属性的值。
        */
    white-space: pre-wrap; word-wrap: break-word; }
    sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
    sup { top: -0.5em; }
    sub { bottom: -0.25em; }
    legend { display: none; border: 0; padding: 0; white-space: normal; }
    fieldset, iframe { border: 0 none; }
    img { border: 0 none; vertical-align: middle; -ms-interpolation-mode: bicubic; }
    button, input, select, textarea { font-family: inherit; font-size: 100%; vertical-align: baseline; }
    button, input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button;  /* 改正iOS设备中“input”类型表单样式不可用的问题 */ cursor: pointer;  /* 增强光标样式在input表单和其他表单的可用性和一致性 */ }
    button[disabled], html input[disabled] { cursor: default;  /* 为禁用表单重设定默认光标样式 */ }
    button::-moz-focus-inner, button::-moz-focus-outer, input::-moz-focus-inner, input::-moz-focus-outer { border: 0 none; padding: 0; margin: 0; }
    input[type="checkbox"], input[type="radio"] { box-sizing: border-box;  /* 调整IE 8/9中尺寸属性设置为“内容框”的盒子模型 */ padding: 0;  /* 去除IE 8/9中的多余的外边距留白部分 */ }
    input[type="search"] { -webkit-appearance: textfield;  /* 兼容Safari 5 and Chrome上 “searchfield” 上设置 “appearance”属性 */  /* 兼容Safari 5 and Chrome上 “border-box” 上设置 “box-sizing”属性 */
    box-sizing: content-box; }
    input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none;  /* 去除OS X系统上Safari 5和Chrome中容器内边距和搜索取消按钮属性 */ }
    input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill { -webkit-box-shadow: 0 0 0 1000px white inset; }
    textarea { overflow: auto; vertical-align: top; resize: vertical; }
    table {  /* 删除表格单元格之间的间距。 */
    border-collapse: collapse; border-spacing: 0; }
    strong { font-weight: normal; }
    img { vertical-align: middle; }
    .clearfix { zoom: 1; clear: both; height: 0; overflow: hidden;  100%; display: block; }
    .clearfix:before, .clearfix:after { content: ""; display: block; height: 0; overflow: hidden; visibility: hidden; }
    .fl { float: left; }
    .fr { float: right; }
    .mauto { float: inherit !important; margin-left: auto; margin-right: auto; }
    fieldset { border: none; }
    input::-webkit-input-placeholder { color: #bfbfbf; }
    input:-ms-input-placeholder { color: #bfbfbf; }
    input:-moz-placeholder { color: #bfbfbf; }
    input::-moz-placeholder { color: #bfbfbf; }
    
    /* 删除选中标签 */
    .tag-checked-name {
        display:inline-block;
        position:relative;
        height: 24px;
        border-radius: 1px;
        color:#4abee0;
        font-size:12px;
        line-height:24px;
        padding:0 20px 0 8px;
        background-color: #f7fdff;
        border: solid 1px #4abee0;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        margin-right:5px;
    }
    .tag-checked-name:first-of-type {
        margin-left: 0px;
    }
    .tag-checked-name em {
       display:block;
        position:absolute;
        top:5px;
        right:5px;
        13px;
        height: 13px;
        cursor:pointer;
        transform: rotate(45deg);
    }
    .tag-checked-name em:after {
        display:block;
        position:absolute;
        content:'';
        top:6px;
        13px;
        height:1px;
        background:#4abee0;
    }
    .tag-checked-name em:before {
        display:block;
        position:absolute;
        content:'';
        top:0px;
        left:5px;
        1px;
        height: 13px;
        background:#4abee0;
    }

    aspect.js

    /**
     * @file aspect
     * @fork https://github.com/ecomfe/saber-lang/blob/master/src/function/aspect.js
     */
    (function () {
    
        /**
         * Aspect
         *
         * @inner
         * @type {Object}
         */
        var Aspect = {};
    
        /**
         * before AOP
         *
         * @private
         * @param {string} method 欲AOP的目标方法名
         * @param {Function} fn AOP处理函数
         * @param {*} context `fn`调用时的上下文
         * @return {Object} 目标对象
         */
        Aspect.before = function (method, fn, context) {
            return aspectTo(this, 'before', method, fn, context);
        };
    
        /**
         * after AOP
         *
         * @private
         * @param {string} method 欲AOP的目标方法名
         * @param {Function} fn AOP处理函数
         * @param {*} context `fn`调用时的上下文
         * @return {Object} 目标对象
         */
        Aspect.after = function (method, fn, context) {
            return aspectTo(this, 'after', method, fn, context);
        };
    
    
        /**
         * 对`目标对象`的`指定方法`进行`AOP`包装
         *
         * @inner
         * @param {Object} target 目标对象
         * @param {string} type AOP方式,可取值 `before` | `after`
         * @param {string} method 欲AOP的目标对象的方法名
         * @param {Function} fn AOP处理函数
         * @param {*} context `fn`调用时的上下文
         * @return {Object} 目标对象
         */
        function aspectTo(target, type, method, fn, context) {
            var oriMethod = target[method];
    
            if (oriMethod) {
                if (type === 'before') {
                    target[method] = function () {
                        // abort support
                        if (fn.apply(context || fn, arguments) !== false) {
                            oriMethod.apply(this, arguments);
                        }
                    };
                }
                else if (type === 'after') {
                    target[method] = function () {
                        oriMethod.apply(this, arguments);
                        fn.apply(context || fn, arguments);
                    };
                }
            }
    
            return target;
        }
    
    
        /**
         * Aspect
         *
         * @exports Aspect
         * @type {Object}
         */
        var exports = {};
    
        /**
         * 将 `Aspect` 混入到目标对象
         *
         * @public
         * @param {Object} obj 目标对象
         * @return {Object} 混入 `Aspect` 后的目标对象
         */
        exports.mixin = function (obj) {
            // 省略了 hasOwnProperty 校验
            /* eslint-disable guard-for-in */
            for (var method in Aspect) {
                obj[method] = Aspect[method];
            }
            /* eslint-enable guard-for-in */
            return obj;
        };
    
        window.AOP =  exports;
    
    })();

    keyWord.js

    /**
     * 定义一个列表数据结构
     * 作用:添加元素、删除元素、清除所有元素,将数据中的元素组装成对象返回一个数据
     * 只针对数据处理
     * @constructor
     */
    function List() {
      this.dataStore = new Array();
      this.listSize = 0;
      this.pos = 0;
    }
    List.prototype = {
      constructor: List,
      append: function(name) {
        this.dataStore[this.listSize++] = name;
      },
      cusPos: function() {
        return this.pos;
      },
      front: function() {
        this.pos = 0;
      },
      end: function() {
        this.pos = this.listSize - 1;
      },
      length: function() {
        return this.listSize;
      },
      prev: function() {
        if (this.pos > 0) {
          --this.pos;
        }
      },
      next: function() {
        if (this.pos < this.listSize) {
          ++this.pos;
        }
      },
      find: function(name) {
        var index = -1;
        this.dataStore.forEach(function(data, i, array) {
          if (data == name) {
            index = i;
          }
        });
        return index;
      },
      remove: function(name) {
    
        var index = this.find(name);
        if (index > -1) {
          this.dataStore.splice(index, 1);
          --this.listSize;
          return true;
        }
    
        return false;
    
    
      },
      getElement: function() {
        return this.dataStore[this.pos];
      },
      clear: function() {
        delete this.dataStore;
        this.dataStore = [];
        this.pos = this.listSize = 0;
      }
    }
    
    /**
     * 定义一个用来对列表操作的对象
     * 对列表的一个包装
     * @param options
     */
    var doKeyWord = function(options) {
    
      var settings = options;
    
      var list = new List();
    
      return AOP.mixin({
        init: function(arr) {
          var that = this;
          // 初始化
          if (typeof arr == "string") {
            arr = arr == '' ? [] : arr.split(',');
          }
          if (typeof arr == 'undefined') {
            arr = [];
          }
          // 清空数据
          list.clear();
          // 便利添加数据中
          arr.forEach(function(data, i, array) {
            that.add(data);
          })
        },
        render: function() {
          // 渲染效果
    
          var valueArr = [],
            html = [],
            name;
    
          for (list.front(); list.cusPos() < list.length(); list.next()) {
            name = list.getElement();
            valueArr.push(name);
            html.push('<div class="tag-checked-name">' + name.substr(0, 10) + '<em data-word-tag-close="' + name + '"></em></div>')
          }
    
          $(settings.panel).html(html.join(''));
          $(settings.value).val(valueArr.join(','));
    
        },
        add: function(name) {
          name = $.trim(name);
          if (name == '') {
            return false;
          }
          // 添加数据
          if (list.find(name) > -1) {
            return false;
          }
          list.append(name);
        },
        remove: function(name) {
          list.remove(name);
        },
        clear: function() {
          list.clear();
        },
        front: function() {
          return list.front();
        },
        end: function() {
          return list.end()
        },
        getElement: function() {
          return list.getElement();
        },
        length: function() {
          return list.length();
        }
      });
    }
    
    $(function() {
    
      $.fn.keyWord = function(options) {
    
        var keyWord = doKeyWord(options);
    
        // 对添加的数据进行检查
        function doCheck() {
          if (options.max < keyWord.length() + 1) {
            alert(options.tips);
            return false;
          }
    
          return true;
        }
    
    
        var render = keyWord.render;
    
        // 添加前检查
        keyWord.before('add', doCheck);
        // 初始化后渲染效果
        keyWord.after('init', render);
        // 添加后渲染效果
        keyWord.after('add', render);
        // 删除后渲染效果
        keyWord.after('remove', render);
    
        var that = $(this);
        // 删除元素
        $(document).on('click', '[data-word-tag-close]', function() {
          var name = $(this).data('word-tag-close');
          // 过滤掉不删除的
          keyWord.remove(name);
        });
        /**
         * Backspace删除 对应的键盘编码
         * e.keyCode == 8 :Backspace键
         */
        that.keydown(function(e) {
          var that = $(this);
          var val = $.trim(that.val());
          if (val == "" && e.keyCode == 8) {
            keyWord.end();
            keyWord.remove(keyWord.getElement());
          }
        });
    
        // 添加数据
        function doAdd(name) {
          name = $.trim(that.val());
          that.val('');
          if (name == '') {
            return;
          }
          keyWord.add(name);
        }
    
        /**
         * 判断有输入空格吗
         * e.keyCode == 32 空格键
         */
        that.keyup(function(e) {
          var that = $(this);
          var isSpaceKey = /s+$/gi.test(that.val());
          // 是空格键输入了一个空格字符
          if (e.keyCode == 32 && isSpaceKey) {
            doAdd(that.val())
          }
        });
        // 鼠标失去焦点
        that.blur(function(e) {
          doAdd(that.val())
        });
    
        this.init = function(arr) {
          keyWord.init(arr);
        }
        return this;
    
      }
    });
  • 相关阅读:
    part17 一些知识总结
    part16 php面向对象
    part15 php函数
    part14 php foreach循环
    part13 数组排序
    part12 php数组
    part11 php条件语句
    part10 php运算符
    part09 php字符串变量
    part08 php常量
  • 原文地址:https://www.cnblogs.com/robinunix/p/8494596.html
Copyright © 2020-2023  润新知