简体   繁体   English

如何在按钮单击时分配前和后功能,而不更改按钮定义或先前编写的功能

[英]How do I assign a pre and post function on button click without changing button definition or previously written functions

I have the following buttons: 我有以下按钮:

<button id="abcd" onclick="something()">click</button>

and the following functions are attached to this button apart from the one in its html definition. 并且此按钮除了其html定义中的功能之外,还附加了以下功能。

$('#abcd').on('click',function(){alert("abcd");});
$('#abcd').on('click',function(){
someAjaxCallWithCallback;
});

Now I want a new function with another ajax call to execute on this button's click, before the above mentioned functions. 现在, 上述功能之前 ,我想要一个带有另一个ajax调用的新功能,以在此按钮的单击上执行。 This new function determines whether the remaining functions would be called or not based on what data is recieved by the ajax call. 这个新函数根据ajax调用接收到的数据确定是否调用其余函数。 That is, this pre function should complete its execution before giving control over to the rest of the functions and also determine whether they would run or not. 也就是说,此前置功能应在将控制权交给其余功能之前完成其执行,并确定它们是否将运行。

As an example, without changing the existing validation logics and button code, I have to add a new pre-validation function and similarly and post validation function. 例如,在不更改现有验证逻辑和按钮代码的情况下,我必须添加一个新的验证前功能,类似地,还要添加验证后功能。

I have a bindFirst method using which I can at least bring my new function to the beginning of the call stack but I have not been able to contain its execution and control further delegation because of callbacks. 我有一个bindFirst方法,使用它至少可以将新函数带到调用堆栈的开头,但是由于回调,我无法包含其执行和控制进一步的委派。

If I understand correctly, you are looking for the way to do this, without modifying html and already existing js, only by adding new js-code. 如果我理解正确,那么您正在寻找做到这一点的方法,而无需修改html和已经存在的js,而只需添加新的js代码即可。

First of all, if onclick handler is set and you want to control it, you should disable it on page load (maybe, saving it to some variable): 首先,如果设置了onclick处理程序并且要对其进行控制,则应在页面加载时将其禁用(也许将其保存到某个变量中):

$(document).ready(function() {
  var onclick = $("#abcd").attr("onclick").split("(")[0];
  //to run it in future: window[onclick]();
  $("#abcd").attr("onclick", "");
});

Edit: I changed my answer a little, previous approach didn't work. 编辑:我稍微改变了我的答案,以前的方法不起作用。

Now you need to remove all already existing handlers. 现在,您需要删除所有已经存在的处理程序。 If number of handlers you want to control is limited, constant and known to you, you can simply call them in if-else after pre-validation inside your pre-function. 如果要控制的处理程序数量有限,恒定且为您所知,则可以在预功能内部通过预验证后在if-else中简单地调用它们。 If you want something more flexible, you are able to get all the handlers before removing, save them and then call them in a loop. 如果您想要更灵活的东西,可以在删除之前获取所有处理程序,保存它们,然后在循环中调用它们。

For that "flexible" solution in the end of $(document).ready(); 对于$(document).ready();结尾的“灵活”解决方案 you save all already existing handlers to an array and disable them. 您将所有已经存在的处理程序保存到一个数组并禁用它们。 Then you write your pre-function and leave it as the only handler. 然后,编写您的前置功能并将其保留为唯一的处理程序。

var handlers = ($._data($("#abcd")[0], "events")["click"]).slice();
$("#abcd").off("click");

$("#abcd").click(function() { 
    //this is your pre-func
    //some code        
    handlers[1].handler.call();
  });

Try console.log($._data($("#abcd")[0], "events")) to see, what it is. 尝试console.log($ ._ data($(“#abcd”)[0],“事件”)))看看它是什么。

Finally just run your post-function and do whatever you need, using conditions. 最后,只需运行您的后功能,并根据条件执行所需的任何操作即可。

So, the general algorithm is as follows: 因此,一般算法如下:

  1. Disable onclick 禁用onclick

  2. Save all handlers 保存所有处理程序

  3. Disable all handlers 禁用所有处理程序

  4. Run pre-func first 先运行功能前

  5. Run handlers you want to be executed 运行要执行的处理程序

  6. Run post-func 运行功能后

In fact, you just make your pre-func the only handler, which can run all other handlers you may need. 实际上,您只需将pre-func设为唯一的处理程序,即可运行您可能需要的所有其他处理程序。

Although Alex was spot on, I just wanted to add more details to cover certain cases that were left open. 尽管找到了Alex ,但我只是想添加更多详细信息,以涵盖尚待解决的某些案例。

class preClass{
constructor(name,id){
    if($(id) && $(id)[0] && $(id)[0]['on'+name])
    {
        var existing = $(id)[0]['on'+name]
        $(id).bindFirst(name,existing);
        $(id).removeAttr('on'+name)
        alert("here");
    }
    if($._data($(id)[0],"events")){
        this.handlers = $._data($(id)[0],"events")[name].slice();
    }
    else
    {
        this.handlers = null;
    }
    this.id = id;
    this.name = name;
}

generatePreMethod(fn,data)
{
    $(this.id).off(this.name);
    $(this.id).bindFirst(this.name,function(){
        $.when(fn()).then(execAll(data));
    });
}
}
function exec(item,index){
    item.handler.call()
}

function execAll(handlers){
   return function(){ handlers.forEach(exec);}
}

This more or less takes care of all the cases. 这或多或少地照顾了所有情况。

Please let me know if there is something I missed! 请让我知道我是否错过了什么!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM