如何在jQuery自定义插件中正确添加多个元素事件

时间:2017-12-04 11:06:12

标签: javascript jquery

我正在尝试编写我的第一个jquery插件,并且在尝试实现函数,事件和触发器时遇到了一些困难。

以下是我工作的场景。

  1. 我有多个具有相同类别的输入框,例如。 "数字框"
  2. 直接将插件应用于这些类,例如。 " $(" .numberTextBox&#34)。inputNumericTextBox();"
  3. 我也可以在其中进行设置。
  4. 现在插件应该只允许基于默认情况下给出的设置的数值。
  5. 我的想法是正确转换并验证任何给定的值。我想同时使用onkeypress和onblur事件。为此,我编写了简单的JavaScript程序,请参阅此处http://jsfiddle.net/wHgH5/29/
  6. 我想创建jquery插件,以便将来可以使用更友好的代码轻松使用。
  7. On"返回每个功能"你可以看到我为了这个特定的原因写了按键和模糊功能。
  8. 我面临的问题:

    1. 首先,模糊事件不起作用,所以我无法在事先驱动之前触发,在事后检查,onComplete函数之后,更不用说triggerBlurAction中的所有功能都不起作用。
    2. 其次,即使在按键事件中,它也假设所有" numberTextBox"输入元素相同,不单独应用。为了理解它运行代码片段,有两个具有相同类的输入框,现在键入/按下键盘" 2.1.1"它只允许" 2.1"在那个输入框中,但在第二个输入框中,它不会允许小数。但如果你清空第一个输入框,它将允许在第二个输入框上写入单个小数。 我想单独执行
    3. 点击此处https://jsfiddle.net/mzhe2rde/

      
      
      //JQuery Custom Plugin inputNumericTextBox
      (function($) {
        jQuery.fn.inputNumericTextBox = function(options) {
      
          var defaults = {
            negativeAllow: true,
            decimalAllow: true,
            decimalError: false,
            negativeSignError: false,
            beforeKeypressAction: function() {},
            afterKeypressAction: function() {},
            beforeBlurAction: function() {},
            afterBlurAction: function() {},
            onError: function() {},
            onComplete: function() {},
          };
      
          var settings = $.extend({}, defaults, options);
      
          return this.each(function(i, element) {
            $(document).on('keypress', element, function(e) {
              triggerKeypressAction(e, element)
            });
            $(document).on('blur', element, function(e) {
              alert(); //for testing but it's now working
              triggerBlurAction(e, element)
            });
          });
      
          function triggerKeypressAction(evt, element) {
            settings.beforeKeypressAction.call(element, settings);
      
            var regex;
            var theEvent = evt || window.event;
            var key = String.fromCharCode(theEvent.keyCode || theEvent.which);
            if (/\./.test(key) && /\./.test($(element).val())) {
              theEvent.returnValue = false;
              if (theEvent.preventDefault) {
                theEvent.preventDefault();
              }
              settings.decimalError = true;
              settings.onError.call(element, settings);
              return false;
            }
      
            /** Any idea on how to allow only one negative sign at the beginning?
               write regex code here **/
      
            if (settings.decimalAllow) {
              regex = (settings.negativeAllow) ? /[0-9]|\-|\./ : /[0-9]|\./;
            } else {
              regex = (settings.negativeAllow) ? /[0-9]|\-/ : /[0-9]/;
            }
            if (!regex.test(key)) {
              theEvent.returnValue = false;
              if (theEvent.preventDefault) theEvent.preventDefault();
            }
      
            settings.afterKeypressAction.call(element, settings);
          }
      
          function triggerBlurAction(evt, element) {
            settings.beforeBlurAction.call(element, settings);
      
            var inputValue = $(element).val(),
              parsedValue = (settings.decimalAllow) ? parseFloat(inputValue) : parseInt(inputValue, 10);
            if (isNaN(parsedValue)) {
              $(element).val('');
            } else if (settings.negativeAllow) {
              $(element).val(parsedValue);
            } else {
              $(element).val(Math.abs(parsedValue));
            }
      
            settings.afterBlurAction.call(element, settings);
            settings.onComplete.call(element, settings);
          }
      
        };
      })(jQuery);
      
      $(".numberTextBox").inputNumericTextBox({
        negativeAllow: true,
        decimalAllow: true,
        beforeKeypressAction: function(e) {
          console.log(this);
          console.log(e);
          console.log('before key');
        },
        afterKeypressAction: function(e) {
          console.log(this);
          console.log(e);
          console.log('after key');
        },
        beforeBlurAction: function(e) {
          console.log(this);
          console.log(e);
          console.log('before blur');
        },
        afterBlurAction: function(e) {
          console.log(this);
          console.log(e);
          console.log('after blur');
        },
        onError: function(e) {
          console.log(this);
          console.log(e);
          console.log('on error');
          if (e.decimalError) {
            alert('More than one decimal number is not allowed');
          } else if (e.negativeSignError) {
            alert('More than one negative sign is not allowed.\n You can only use negative at the start');
          }
        },
        onComplete: function(e) {
          console.log(this);
          console.log(e);
          console.log('on complete');
        },
      
      });
      
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      
      <body>
        <input id="firstbox" type="text" class="numberTextBox" />
        <input id="secondbox" type="text" class="numberTextBox" />
      </body>
      &#13;
      &#13;
      &#13;

1 个答案:

答案 0 :(得分:1)

我以为我应该试试自己。我所做的是将插件的所有内容放到另一个私有函数中。并在循环中调用该函数以分别初始化每个元素。这样我实现了目标,所有事件都正常运作。还有更多支持单一的负号。现在它是正确的输入数字文本框。

在这里查看https://jsfiddle.net/mzhe2rde/6/

&#13;
&#13;
//JQuery Custom Plugin inputNumericTextBox
(function($) {
    "use strict";

    var inputNumericTextBox = function(element, options) {
        var previous_value_set = false;
        var previous_value = '';
        var defaults = {
            negativeAllow: true,
            decimalAllow: true,
            decimalError: false,
            startNegativeSignError: false,
            multipleNegativeSignError: false,
            beforeKeypressAction: function() {},
            afterKeypressAction: function() {},
            beforeKeyupAction: function() {},
            afterKeyupAction: function() {},
            beforeBlurAction: function() {},
            afterBlurAction: function() {},
            onError: function() {},
            onInitializationComplete: function() {},
        };

        var settings = $.extend({}, defaults, options);

        $(element).on('keypress', function(e) {
            //console.log("keypress");
            triggerKeypressAction(e, element);
        });
        $(element).on('keyup', function(e) {
            //console.log("keyup");
            triggerKeyupAction(e, element);
        });
        $(element).on('blur', function(e) {
            //console.log("blur");
            triggerBlurAction(e, element);
        });

        settings.onInitializationComplete.call(element, settings);

        function triggerKeypressAction(evt, element) {
            settings.beforeKeypressAction.call(element, settings);

            var regex;
            var theEvent = evt || window.event;
            var key = String.fromCharCode(theEvent.keyCode || theEvent.which);
            if (/\./.test(key) && /\./.test($(element).val())) {
                theEvent.returnValue = false;
                if (theEvent.preventDefault) {
                    theEvent.preventDefault();
                }
                settings.decimalError = true;
                settings.onError.call(element, settings);
                settings.afterKeypressAction.call(element, settings);
                settings.decimalError = false;
                return false;
            }

            if (/-/.test(key) && /-/.test($(element).val())) {
                theEvent.returnValue = false;
                if (theEvent.preventDefault) {
                    theEvent.preventDefault();
                }
                settings.multipleNegativeSignError = true;
                settings.onError.call(element, settings);
                settings.afterKeypressAction.call(element, settings);
                settings.multipleNegativeSignError = false;
                return false;
            }

            if (/-/.test(key)) {
                previous_value_set = true;
                previous_value = $(element).val();
            }

            if (settings.decimalAllow) {
                regex = (settings.negativeAllow) ? /[0-9]|-|\./ : /[0-9]|\./;
            } else {
                regex = (settings.negativeAllow) ? /[0-9]|-/ : /[0-9]/;
            }
            if (!regex.test(key)) {
                theEvent.returnValue = false;
                if (theEvent.preventDefault) theEvent.preventDefault();
            }
            settings.afterKeypressAction.call(element, settings);
        }

        function triggerKeyupAction(evt, element) {
            settings.beforeKeyupAction.call(element, settings);

            if (settings.negativeAllow && previous_value_set) {
                if (!(/^-.*/.test($(element).val()))) {
                    $(element).val(previous_value);
                    settings.startNegativeSignError = true;
                    settings.onError.call(element, settings);
                    settings.startNegativeSignError = false;
                }
            }
            previous_value_set = false;
            previous_value = '';

            settings.afterKeyupAction.call(element, settings);
        }

        function triggerBlurAction(evt, element) {
            settings.beforeBlurAction.call(element, settings);

            var inputValue = $(element).val(),
                parsedValue = (settings.decimalAllow) ? parseFloat(inputValue) : parseInt(inputValue, 10);
            if (isNaN(parsedValue)) {
                $(element).val('');
            } else if (settings.negativeAllow) {
                $(element).val(parsedValue);
            } else {
                $(element).val(Math.abs(parsedValue));
            }

            settings.afterBlurAction.call(element, settings);
        }
        return;
    };

    if (!jQuery.fn.inputNumericTextBox) {
        jQuery.fn.inputNumericTextBox = function(options) {
            return this.each(function() {
                inputNumericTextBox(this, options);
                return this;
            });
        };
    }

})(jQuery);

$(".numberTextBox").inputNumericTextBox({
    negativeAllow: true,
    decimalAllow: true,
    beforeKeypressAction: function(e) {
        //console.log(this);
        //console.log(e);
        //console.log('before keypress');
    },
    afterKeypressAction: function(e) {
        //console.log(this);
        //onsole.log(e);
        //console.log('after keypress');
    },
    beforeKeyupAction: function(e) {
        //console.log(this);
        //onsole.log(e);
        //console.log('before keyup');
    },
    afterKeyupAction: function(e) {
        //console.log(this);
        //onsole.log(e);
        //console.log('after keyup');
    },
    beforeBlurAction: function(e) {
        //console.log(this);
        //console.log(e);
        //console.log('before blur');
    },
    afterBlurAction: function(e) {
        //console.log(this);
        //console.log(e);
        //console.log('after blur');
    },
    onError: function(e) {
        //console.log(this);
        //console.log(e);
        //console.log('on error');
        if (e.decimalError) {
            alert('More than one decimal number is not allowed');
        } else if (e.multipleNegativeSignError) {
            alert('More than one negative sign is not allowed.');
        } else if (e.startNegativeSignError) {
            alert('You can only use one negative sign at the start');
        }
    },
    onInitializationComplete: function(e) {
        //console.log(this);
        //console.log(e);
        //console.log('on complete');
    },

});

/* Last initialization settings will take the precedence but events will trigger on all initialization
 * You shouldn't initialize more than one on a single element because it will create more object and it will take some memory to store it.
 * It's their to support large environment */

/* This is an example of last initialization or initialization more than one */

/*  
$(".numberTextBox").inputNumericTextBox();
var n = $(".numberTextBox").inputNumericTextBox({
    negativeAllow: false,
    decimalAllow: true
});
console.log(n);*/
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
    <input type="text" class="numberTextBox" />
    <input type="text" class="numberTextBox" />
</body>
&#13;
&#13;
&#13;