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

Posted

技术标签:

【中文标题】如何在 jQuery 自定义插件中正确添加多个元素事件【英文标题】:How to properly add multiple elements event in jQuery custom plugin 【发布时间】:2017-12-04 11:06:12 【问题描述】:

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

这是我工作的场景。

    我有多个具有相同类的输入框,例如。 “数字文本框” 将插件直接应用于这些类,例如。 "$(".numberTextBox").inputNumericTextBox();". 我也可以在里面进行设置。 现在插件应该只允许基于默认设置的数值。 我的想法是正确转换和验证任何给定值。我想同时使用 onkeypress 和 onblur 事件。为此,我编写了简单的 javascript 程序,请参见此处http://jsfiddle.net/wHgH5/29/。 我想创建 jquery 插件,这样我以后可以通过更友好的代码轻松使用。 在“返回每个函数”中,您可以看到我出于特定原因编写了按键和模糊函数。

我面临的问题:

    首先,模糊事件不起作用,因此我无法触发 beforeBlurAction、afterBlurAction、onComplete 函数,更不用说 triggerBlurAction 中的所有功能都不起作用。 其次,即使在按键事件中,它也假设所有“numberTextBox”输入元素都是相同的,并且不单独应用。要理解它,运行代码 sn-p 有两个具有相同类的输入框,现在从键盘“2.1.1”键入/按下它只会在该输入框中允许“2.1”,但在第二个输入框中它不会允许十进制。但是如果你清空第一个输入框,它将允许在第二个输入框上写一个十进制。 我想分开做

在这里查看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>

【问题讨论】:

【参考方案1】:

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

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

//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);*/
<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>

【讨论】:

以上是关于如何在 jQuery 自定义插件中正确添加多个元素事件的主要内容,如果未能解决你的问题,请参考以下文章

怎样在Vue.js中使用jquery插件

怎样在Vue.js中使用jquery插件

自定义 jQuery 不适用于 Wordpress Ninja Forms 插件

使用带有Notify.js jQuery插件的外部自定义CSS

使用 jQuery 验证插件显示自定义元素和内容

jquery-leonaScroll-1.1-自定义滚动条插件