我正在写一个附加组件。我需要在某些方面修改现有的javascript / jquery。它根据输入计算价格。伪代码(原始js我需要修改):
input.onEvent
get Input Values
calculate 'price' from input values
我需要修改计算出的价格。所以我需要以这样的方式修改原始的js:
modified price = triggerEvent('modifyThePrice', price)
用语言:我需要调用一个钩子,然后其他的javascript就可以完成他们的工作并在需要时修改价格(或者像带有return语句的事件)......
根据要求我还会添加更精确的代码..
$('form#buy').bind('price-update', function(){
/*
* a LOT of code, getting input, calculating price. at the end we have a var
*price which is numeric
*/
//What I need to do now
var modified_price = modifyPrice(price);
});
只是modifyPrice(price)必须调用页面上的每个其他js,这样每个人都有机会进行交互。
知道wordpress的那些人:我需要做一些可以用wp完成的事情:$modified_price = apply_filters('modify_price', $price);
每个人都可以将函数绑定到'modify-price'钩子
我希望这有助于理解问题
答案 0 :(得分:2)
这个怎么样?首先,过滤器模块:
var filter = {
filters: {},
add: function (tag, filter) {
(this.filters[tag] || (this.filters[tag] = [])).push(filter);
},
apply: function (tag, val) {
if(this.filters[tag]){
var filters = this.filters[tag];
for(var i = 0; i < filters.length; i++){
val = filters[i](val);
}
}
return val;
}
}
然后添加过滤器:
filter.add('modify_name', function(name){
name = 'MR. ' + name;
return name;
});
并应用过滤器:
name = filter.apply('modify_name', name);
或者,以下是使用dom事件的方法:
$(window).on('modify_name', function (e, data) {
data.name = 'MR. ' + data.name;
});
var data = {};
data.name = 'joe';
$(window).trigger('modify_name', data);
注意:jQuery.trigger
不会返回事件侦听器中的值,因此挂钩必须直接更改数据,而不是返回数据。此外,在Javascript中,除了对象之外,您无法通过引用传递值。因此,为了传递数据进行修改,我们必须先将它存储在一个对象中,然后将该对象传递给钩子。
答案 1 :(得分:0)
这个支持 namespace 的简单JavaScript钩子系统会将所有钩子函数存储在一个名为hooks
的对象中:
var hooks = {}; // store all hooks here
function on(name, fn) {
name = name.split('.');
if (!hooks[name[0]]) hooks[name[0]] = {};
var i = name[1] || Object.keys(hooks[name[0]]).length;
hooks[name[0]][i] = fn;
}
function off(name) {
if (!name) {
return hooks = {};
}
name = name.split('.');
if (name[1]) {
delete hooks[name[0]][name[1]];
} else {
delete hooks[name[0]];
}
}
function trigger(name, param) {
name = name.split('.');
if (!hooks[name[0]]) hooks[name[0]] = {};
if (name[1]) {
if (hooks[name[0]][name[1]]) hooks[name[0]][name[1]].apply({}, param);
} else {
for (var i in hooks[name[0]]) {
hooks[name[0]][i].apply({}, param);
}
}
}
&#13;
<p>
<button onclick="on('click',function(){alert('hook `'+(new Date()).getTime()+'` added!')});">Add a <code>click</code> Hook</button>
<button onclick="on('click.foo',function(){alert('hook `click.foo` added!')});">Add a <code>click</code> Hook with ID <code>foo</code></button>
</p>
<p>
<button onclick="off('click');">Remove All <code>click</code> Hooks</button>
<button onclick="off('click.foo');">Remove a <code>click</code> Hook with ID <code>foo</code></button>
</p>
<p>
<button onclick="trigger('click');">Trigger All <code>click</code> Hooks</button>
<button onclick="trigger('click.foo');">Trigger <code>click</code> Hook with ID `foo`</button>
</p>
&#13;
// add a `click` hook
on("click", function(x) {
alert('test ' + x + ' ok!');
});
// add a `click` hook with `foo` namespace
on("click.foo", function(x) {
alert('test ' + x + ' foo ok!');
});
// remove all `click` hooks
off("click");
// remove `click.foo` hook only
off("click.foo");
// trigger all `click` hooks
trigger("click", ['this will be the `x`', 'this will be the second function parameter…']);
// trigger `click.foo` hook only
trigger("click.foo", ['this will be the `x`', 'this will be the second function parameter…']);
如果要返回值,请改用此代码段:
var hooks = {}; // store all hooks here
function add_filter(name, fn) {
name = name.split('.');
if (!hooks[name[0]]) hooks[name[0]] = {};
var i = name[1] || Object.keys(hooks[name[0]]).length;
hooks[name[0]][i] = fn;
}
function remove_filter(name) {
if (!name) {
return hooks = {};
}
name = name.split('.');
if (name[1]) {
delete hooks[name[0]][name[1]];
} else {
delete hooks[name[0]];
}
}
function apply_filter(name, value, param) {
name = name.split('.');
if (!hooks[name[0]]) hooks[name[0]] = {};
if (name[1]) {
if (hooks[name[0]][name[1]]) {
value = hooks[name[0]][name[1]].apply(value, param);
}
} else {
for (var i in hooks[name[0]]) {
value = hooks[name[0]][i].apply(value, param);
}
}
return value;
}
// add a `test` filter
add_filter("test", function(v) {
return v + ' test!';
});
// add a `test` filter with `foo` namespace
add_filter("test.foo", function(v) {
return v + ' test.foo!';
});
// remove all `test` filters
remove_filter("test");
// remove `test.foo` filter only
remove_filter("test.foo");
// apply all `test` filters
return apply_filter("test", 'initial value', [param_1, param_2]);
// apply `test.foo` filter only
return apply_filter("test.foo", 'initial value', [param_1, param_2]);