【问题标题】:Why doesn't the change event fire on selector.val(1234)? [duplicate]为什么没有在 selector.val(1234) 上触发 change 事件? [复制]
【发布时间】:2011-03-24 20:21:05
【问题描述】:

可能重复:
jQuery textbox.val('xxxx') not causing change to fire?

我有一个插件应该在“选择器”的值更新时触发。在正常的 UI 交互过程中,它就像一个冠军。但是,如果“选择器”通过 JavaScript 或 jQuery 更新,它不会触发。

  • 直接通过文本框更新...有效
  • 按下按钮...失败
  • 使用 jQuery 调用对 selected.val(xxx) 进行更新...失败

插件的总体思路是自动对网格和面板等内容进行四舍五入。

任何帮助都会很棒...我整天都在努力解决这个问题!

给定以下 HTML:

<input id="myDecimalTotal" type="text" value="0.00" class="rounder-decimal" />
<input id="btnDecimalTotalTest" type="button" value="Run Total" />

使用以下选择器和 JavaScript 进行测试:

jQuery(document).ready(function() {
   jQuery('input.rounder-decimal').numericRounder();
   jQuery('#btnDecimalTotalTest').click(overwriteDecimalTotal);    // fails
   jQuery('#myDecimalTotal').val(777);                             // fails
});

function overwriteDecimalTotal() {
   jQuery('#myDecimalTotal').val(123);
}

对于以下插件:

(function($) {
    $.fn.numericRounder = function(options) {

        switch (typeof (options)) {
            case 'object':
                options = $.extend({}, $.fn.numericRounder.defaults, options);
                break;
            case 'string':
                options = $.extend({}, $.fn.numericRounder.defaults, { onEvent: options });
                break;
            default:
                options = $.fn.numericRounder.defaults;
        }

        return this.each(function() {

            var element = $(this);

            if (element.is('input.rounder-decimal')) {
                switch (options.onEvent) {
                    case 'change':
                        element.change(roundDecimal);
                        break;
                    case 'blur':
                        element.blur(roundDecimal);
                        break;
                    case 'click':
                        element.click(roundDecimal);
                        break;
                    default:
                        element.blur(roundDecimal);
                }
            }

            if (element.is('input.rounder-wholeNumber')) {
                switch (options.onEvent) {
                    case 'change':
                        element.change(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    case 'blur':
                        element.blur(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    case 'click':
                        element.click(function() { roundWholeNumber(this, options.factorOf); });
                        break;
                    default:
                        element.blur(function() { roundWholeNumber(this, options.factorOf); });
                }
            }

            /// <summary>Rounds a numeric value to the nearest place.</summary>
            function roundDecimal() {

                var value = $(this).val();
                value = extractValue(value);

                if (isNaN(value))
                    value = $(this).val();
                else
                    value = Math.round(value).toFixed(2);

                $(this).val(value);
            }
            /// <summary>Rounds a numeric value to the nearest place.</summary>
            function roundWholeNumber(element, factorOf) {

                var value = $(element).val();
                value = extractValue(value);

                if (isNaN(value))
                    value = $(element).val();
                else
                    value = Math.round(value / factorOf) * factorOf;

                $(element).val(value);
            }
            /// <summary>Extracts the number.</summary>
            function extractValue(value) {
                var numericRegEx = /([\d\.])/g;

                try {
                    return value.match(numericRegEx).join('');
                }
                catch (error) {
                    return value;
                }
            }
        });
    };

    /// <summary>Default options.</summary>
    $.fn.numericRounder.defaults = { onEvent: 'change', factorOf: 10 };
})(jQuery);

【问题讨论】:

    标签: javascript jquery jquery-plugins jquery-events


    【解决方案1】:

    据我所知,情况就是这样。从 JavaScript 更改值时不会触发 change 事件。触发它很容易(使用 jQuery):

    jQuery('#myDecimalTotal').val(123).change();
    

    这将触发该元素上的所有 change 事件处理程序。

    【讨论】:

      【解决方案2】:

      使用 .val() 更新文本框时,jQuery 不会触发事件

      更改值后尝试手动触发事件:

      jQuery('#myDecimalTotal').val(777).trigger('change');
      

      【讨论】:

        【解决方案3】:

        这是事件处理的浏览器限制,但您可以声明自己的事件并为您的事件设置监听器。您所要做的就是在需要时触发您的事件。

        //callback function
        function overwriteDecimalTotal() {
           jQuery('#myDecimalTotal').val(123);
        }
        
        //add event listener
        jQuery('#myDecimalTotal').bind('changeValue', function () { 
         overwriteDecimalTotal();
        })
        
        //trigger your event when needed
        jQuery('#myDecimalTotal').val(777).trigger('changeValue');
        

        【讨论】:

          【解决方案4】:

          这是一个小提琴,展示了如何使用触发更改来正确更新您的数字

          http://jsfiddle.net/dLfmV/3/

          修复链接

          【讨论】:

          • 对不起,小提琴的例子似乎不起作用。
          • 奇怪...它似乎没有保存它的最新版本。对此感到抱歉!
          • 啊,好多了。
          猜你喜欢
          • 1970-01-01
          • 2016-12-11
          • 2016-09-03
          • 1970-01-01
          • 1970-01-01
          • 2015-11-02
          • 2011-04-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多