jQuery.ajax 从 dateRangeSlider 中的 userValuesChanged 调用了两次

Posted

技术标签:

【中文标题】jQuery.ajax 从 dateRangeSlider 中的 userValuesChanged 调用了两次【英文标题】:jQuery.ajax called twice from userValuesChanged in dateRangeSlider 【发布时间】:2014-11-03 17:33:16 【问题描述】:

我正在使用 jQDateRangeSlider 来触发 jQuery.ajax 调用。有两种方法可以移动滑块。

    单独移动滑块的两端 通过将整个突出显示的块从一个位置移动到另一个位置

如果是 1,我的代码可以正常工作,但如果是 2,'userValuesChanged' 会被调用两到四次。这是小部件的一些错误还是我在这里做错了什么?我的代码是这样的吗?

function init() 
    var tp = $('tp').value;
    if (tp == 'Daily') 
        dataFile1 = "http://localhost:8080/composite2/Composite/datejson";

        d3.json(dataFile1, function (error, data) 
            if (data) dataset1 = data;
            var min = dataset1[0].a;
            var jugad = dataset1[0].c;
            jugad2 = new Date(jugad);
            var min2 = new Date(min);
            var max = dataset1[dataset1.length - 1].b;
            var max2 = new Date(max);

            function addZero(val) 
                if (val < 10) 
                    return "0" + val;
                
                return val;
            
            var s = $j("#slider").dateRangeSlider(

                bounds: 
                    "min": min2,
                    "max": max2
                ,
                range: 
                    min: 
                        hours: 25
                    ,
                    max: 
                        days: 7
                    ,
                ,
                formatter: function (val) 
                    var m = moment(val);
                    return m.format("DD/MM/YYYY HH:00:00 ");
                ,
                defaultValues: 
                    min: min2,
                    max: max2
                
            );
            x = jugad2;
            x.setMinutes(0);
            x.setSeconds(0);
            z = x.getFullYear() + '-' + (x.getMonth() + 1) + '-' + x.getDate() + ' ' + x.getHours() + ':' + '00' + ':' + '00';
            var y = (s.dateRangeSlider("values").max);
            y.setMinutes(0);
            y.setSeconds(0);
            b = y.getFullYear() + '-' + (y.getMonth() + 1) + '-' + y.getDate() + ' ' + y.getHours() + ':' + '00' + ':' + '00'
            jQuery.ajax(
                type: 'POST',
                data: 'metric=' + $('metric').value + '&tp=' + $('tp').value + '&date_hour=' + z + '&date_hour=' + b,
                url: '/composite2/Composite/ajaxGetMv',
                success: function (data, textStatus) 
                    loadData(data);
                ,
                error: function (XMLHttpRequest, textStatus, errorThrown) 
            );

            $j('#slider').on("userValuesChanged", function (e, data) 
                var x = data.values.min;
                x.setMinutes(0);
                x.setSeconds(0);
                z = x.getFullYear() + '-' + (x.getMonth() + 1) + '-' + x.getDate() + ' ' + x.getHours() + ':' + '00' + ':' + '00';
                var last = data.values.max;
                last.setMinutes(0);
                last.setSeconds(0);
                b = last.getFullYear() + '-' + (last.getMonth() + 1) + '-' + last.getDate() + ' ' + last.getHours() + ':' + '00' + ':' + '00';
                jQuery.ajax(
                    type: 'POST',
                    data: 'metric=' + $('metric').value + '&tp=' + $('tp').value + '&date_hour=' + z + '&date_hour=' + b,
                    url: '/composite2/Composite/ajaxGetMv',
                    success: function (data, textStatus) 
                        loadData(data);
                    ,
                    error: function (XMLHttpRequest, textStatus, errorThrown) 
                );
            )
        );
     //end of Daily Slider
 //end of init()

更新

init() 被函数决定调用。

function decide()

var tp = $('tp').value;
if (tp == 'Daily')


  init();

 else
 

  init1();
 

这个函数decision()在下拉'tp'的onchange上被调用

【问题讨论】:

请花时间正确格式化您的代码。这将使您和其他人更容易阅读。 您本可以删除不需要的console.log(),而不是按原样转储整个代码... 抱歉,已删除!感谢您指出。! 你怎么打电话给init() 请检查更新。 【参考方案1】:

我不得不在这里猜测一下,因为你没有说你正在使用什么版本的库。但是,我在 jsFiddle 中测试了插件,它工作正常,所以我假设您正在重复调用 init,这些调用将额外的处理程序绑定到事件。你说:

这个函数decide()在下拉tp的onchange上被调用

这意味着每当下拉列表更改时,init 就会再次被调用,并且处理程序会再次添加到该事件中。您可以在我的jsFiddle 中看到这种情况,计数是正常的,直到您单击按钮再次呼叫init()。有几种方法可以解决这个问题,请参阅 fiddle 中的 cmets。

选项 1 -- 简单但不是很优雅。

只需在 init() 例程开始时销毁滑块:

function init()       
    $j("#slider").dateRangeSlider("destroy");

如果滑块尚未初始化,这不会引发错误(看起来插件有一些健全性检查),但它可能会导致某些浏览器出现视觉故障。

选项 2 -- 更好一点

使用全局变量记录您是否创建了事件

var is_init = false;
function init()  

    // ... other code ... 

    if (!is_init) 
    
        $j('#slider').on("userValuesChanged", function (e, data) 
            // ... handler code ... 
        );
        is_init = true;
     

还有一些其他方法可以使用“全局变量”的想法,包括伪造静态函数变量,但这是一种简单的方法,并且它可能会起作用,因为您有两个 init 例程。

选项 3 -- 可能是我的选择

您的init() 函数实际上是一个(重新)init,因为它可以被多次调用。您只想绑定一次处理程序,因此您可以在 init 函数之外执行它(或在只调用一次的不同函数内)。您可以在调用 init 之前执行此操作,就在页面加载之后。这工作它只是注册一个事件处理程序,它不在乎那个元素不能生成事件,它稍后会处理它。这是一个fiddle。

听起来你真的想要一个被调用一次的init 函数(不绑定到一个元素)和一个绑定到下拉列表的reinit 函数,它只是更改值但不重新绑定事件。我在您的事件处理程序中看不到任何根据不同设置而变化的内容,但如果有的话,您可能不得不使用选项 1。

还有一些其他选项(取消绑定事件处理程序,检测是否已经绑定了处理程序)但如果其他处理程序也绑定到该事件,它们可能会遇到更多麻烦。

这可能不是您的问题的根本原因,但我希望小提琴在任何情况下都能帮助您。

【讨论】:

以上是关于jQuery.ajax 从 dateRangeSlider 中的 userValuesChanged 调用了两次的主要内容,如果未能解决你的问题,请参考以下文章

如何从 jQuery.ajax 获取响应状态码?

从 jquery $.ajax 到 angular $http

jQuery 不会从 AJAX 查询中解析我的 JSON

从 JQuery.ajax 成功数据中解析 JSON

从 PHP (jQuery/AJAX) 插入 MySQL

jQuery.ajax 从 dateRangeSlider 中的 userValuesChanged 调用了两次