highcharts覆盖addEvent函数



在highcharts javascript文件行号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);
}

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

(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/

您可以通过wrap函数覆盖此函数。

我会试试这个:

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

使用wrap实用程序不可能在第1126行重现修改addEvent源代码的效果,因为由于我不完全理解的原因,wrap没有应用于对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/

使用Highcharts.wrap()修改Highcharts.addEvent不起作用,因为Highcharts保存了对addEvent的内部引用。更改外部Highcharts.addEvent对内部引用没有影响。


向后追溯代码,您会发现addEvent来自window.HighchartsAdapter。通过加载适当的适配器,可以使Highcharts与其他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响应,因为浏览器应该已经缓存了第一个请求中的文件。


虽然这可能暂时有效,但从长远来看,monkey-patching他人的代码并不是最好的方法,例如,您或其他开发人员可能会决定在一年后升级到Highcharts的最新版本(使用完全不同的内部API),而不会意识到/记住这一变化。在采用猴子补丁之前,我会考虑其他方法来做你想做的事情。

注意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.

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

以兼容所有浏览器的方式轻松使用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。FireFox和OPERA来自除IE和SAFARI之外的MOZILLA。因此,从1980年到2019年,您的代码将与所有现有浏览器兼容

最新更新