highcharts覆盖addEvent函数

时间:2014-02-17 19:00:04

标签: javascript jquery highcharts

highcharts javascript file第1126行中的

有一个函数 addEvent

/**
         * Add an event listener
         * @param {Object} el A HTML element or custom object
         * @param {String} event The event type
         * @param {Function} fn The event handler
         */
        addEvent: function (el, event, fn) {
            $(el).bind(event, fn);
        },

我想调用自定义函数而不是默认函数,同时我不想更改highcharts.js。

我想通过外部函数分配它,有什么方法可以实现这个吗?

我的新代码

addEvent: function (el, event, fn) {
    if(typeof(fn)=="string"){
        try {
            eval(fn); 
        } catch (e) {
        if (e instanceof SyntaxError) {
            console.log(e.message);
        }
        }

    }
    $(el).bind(event, fn);
}

7 个答案:

答案 0 :(得分:1)

不幸的是,我不知道为什么包装addEvent不起作用(虽然应该!),但你可以覆盖或包装importEvents for point,做类似的事情(但只针对点):

(function (H) {
    H.wrap(H.Point.prototype, 'importEvents', function () {
        if (!this.hasImportedEvents) {
            var point = this,
                options = H.merge(point.series.options.point, point.options),
                events = options.events,
                eventType;

            point.events = events;

            for (eventType in events) {
                if (typeof events[eventType] == "string") {
                    try {
                        events[eventType] = eval(events[eventType]);
                    } catch (e) {
                        if (e instanceof SyntaxError) {
                            console.log(e.message);
                        }
                    }
                }
                H.addEvent(point, eventType, events[eventType]);
                this.hasImportedEvents = true;
            }
        }
    });
}(Highcharts));

演示:http://jsfiddle.net/cXS5u/

答案 1 :(得分:0)

您可以通过wrap功能覆盖此功能。

答案 2 :(得分:0)

我会试试这个:

Highcharts.addEvent = (function(orig) {
  return function(el, event, fn) {
    if(typeof fn == "string") {
        try {
            eval(fn); 
        } catch (e) {
          if (e instanceof SyntaxError) {
            console.log(e.message);
          }
        }
    }

    orig(el, event, fn);
  };
})(Highcharts.addEvent);

使用Highcharts'wrap方法,这应该是

(function(H) {
  H.wrap(H, "addEvent", function(addEvent, el, event, fn) {
    if(typeof fn == "string") {
      try {
        eval(fn); 
      } catch (e) {
        if (e instanceof SyntaxError) {
          console.log(e.message);
        }
      }
    }

    addEvent(el, event, fn);
  });
})(Highcharts);

答案 3 :(得分:0)

不可能通过使用wrap实现重现在第1126行修改addEvent的源代码的效果,因为由于我不完全理解的原因,包裹不适用于许多内部调用到addEvent,包括由初始配置中指定的事件触发的那些,例如你在plotOptions / series / point / events下的事件。

但是,如果像这样添加事件,则会将事件应用于事件:

(function (H) {
    Highcharts.Chart.prototype.callbacks.push(function (chart) {
        H.addEvent(chart.container, 'click', function() { alert('click!') });
    });
}(Highcharts));

或在您的情况下,将函数作为字符串添加到点事件:

(function (H) {
    Highcharts.Chart.prototype.callbacks.push(function (chart) {    
        H.addEvent(chart.series[0].data, 'click', "(function() { alert (this.y);})");
    });
}(Highcharts));

所以你的wrap函数可以像这样处理这两个:

(function (H) {
    H.wrap(H, "addEvent", function (addEvent, el, event, fn) {
        if (typeof fn == "string") {
            try {
                var evalfn = eval(fn);
                addEvent(el, event, evalfn);
            } catch (e) {
                if (e instanceof SyntaxError) {
                    console.log(e.message);
                }
            }
        } else {
            addEvent(el, event, fn);
        }
    });
})(Highcharts);

我授予的并不是你所要求的,但可能会为你想要达到的目标提供另一种解决方案。

在此演示所有这些:http://jsfiddle.net/8wRAs/

答案 4 :(得分:0)

使用Highcharts.addEvent修改Highcharts.wrap()不起作用,因为Highcharts saves an internal referenceaddEvent。更改外部Highcharts.addEvent对内部参考没有影响。


稍微向后追踪代码,您会发现addEvent comes from window.HighchartsAdapter。可以通过loading the appropriate adapter使高密舍图与其他JavaScript框架一起使用,该框架使用适用于特定框架的版本覆盖默认的window.HighchartsAdapter

要在Highcharts保存内部引用之前修改默认适配器上的addEvent,我们可以加载主JS文件两次:(demo

<script src="http://code.highcharts.com/highcharts.js"></script>
<script>
    // Highcharts detects if it has been loaded more than once
    // and throws an error to alert developers
    // We work around this by unsetting the Highcharts object
    window.Highcharts = null;

    window.HighchartsAdapter.addEvent = function (el, event, fn) {
        // add your custom code here

        $(el).bind(event, fn);
    };
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>

这将导致为JS文件发出第二个HTTP请求,但它应该返回304响应,因为浏览器应该已经从第一个请求缓存了该文件。


虽然这可能现在有用,但猴子修补其他人的代码并不是长期进行的最佳方式,例如:您或其他开发人员可能会决定从现在起一年内升级到最新版本的Highcharts(使用完全不同的内部API),而不会意识到/记住此更改。在采用猴子补丁之前,我会考虑其他方法来做你想要做的事情。

答案 5 :(得分:0)

请注意highcharts.js中的这些代码行:

// check for a custom HighchartsAdapter defined prior to this file
var globalAdapter = win.HighchartsAdapter,
    adapter = globalAdapter || {};

// Initialize the adapter
if (globalAdapter) {
    globalAdapter.init.call(globalAdapter, pathAnim);
}


// Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object
// and all the utility functions will be null. In that case they are populated by the
// default adapters below.

由于addEvent中指定了window.HighchartsAdapter,您需要创建一个自定义HighchartsAdapter来覆盖它。在github上有一个自定义highcharts适配器的示例。

答案 6 :(得分:0)

以与所有浏览器兼容的方式轻松使用DOM事件。这是经验...

创建您的函数,例如mouseup ...

var MeObjectDOM_mouseup = function(){
           Me blabla code....
}

立即创建活动...

if(MeObjectDOM.addEventListener){
 MeObjectDOM.addEventListener("mouseup", MeObjectDOM_mouseup ,true);
}else if(MeObjectDOM.attachEvent){
MeObjectDOM.attachEvent("mouseup", MeObjectDOM_mouseup);
}else{
 MeObjectDOM['onmouseup'] = MeObjectDOM_mouseup;
};

您的事件现在与IE,NETSCAPE,CHROME,EDGE,OPERA,FIREFOX,SAFARI兼容,甚至与Safari 5或IE 5、6和Netscape 4(^ __ ^)等旧版本兼容。

  • Chrome Mozilla,它是Netscape,后来被Google恢复。除IE和SAFARI外,FireFox和OPERA来自MOZILLA。因此,您的代码将与1980年以来的所有现有浏览器兼容,直到2019年之前,您还将看到更多....