Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在不更改按钮定义或以前编写的函数的情况下,在单击按钮时分配前置和后置函数_Javascript_Jquery - Fatal编程技术网

Javascript 如何在不更改按钮定义或以前编写的函数的情况下,在单击按钮时分配前置和后置函数

Javascript 如何在不更改按钮定义或以前编写的函数的情况下,在单击按钮时分配前置和后置函数,javascript,jquery,Javascript,Jquery,我有以下按钮: <button id="abcd" onclick="something()">click</button> 现在,我想要一个新函数,在上面提到的函数之前,单击此按钮执行另一个ajax调用。这个新函数根据ajax调用接收到的数据确定是否调用其余函数。也就是说,这个前置函数应该在将控制权交给其余函数之前完成其执行,并确定它们是否会运行 例如,在不更改现有验证逻辑和按钮代码的情况下,我必须添加一个新的预验证函数以及类似的后验证函数 我有一个bindFirst

我有以下按钮:

<button id="abcd" onclick="something()">click</button>
现在,我想要一个新函数,在上面提到的函数之前,单击此按钮执行另一个ajax调用。这个新函数根据ajax调用接收到的数据确定是否调用其余函数。也就是说,这个前置函数应该在将控制权交给其余函数之前完成其执行,并确定它们是否会运行

例如,在不更改现有验证逻辑和按钮代码的情况下,我必须添加一个新的预验证函数以及类似的后验证函数


我有一个bindFirst方法,使用它我至少可以将我的新函数带到调用堆栈的开头,但由于回调,我无法控制它的执行和进一步的委托。

如果我理解正确,您正在寻找这样做的方法,而无需修改html和现有的js,只有通过添加新的js代码

首先,如果设置了onclick处理程序,并且您想要控制它,那么应该在页面加载时禁用它(可能,将其保存到某个变量):

编辑:我稍微更改了我的答案,以前的方法不起作用

现在您需要删除所有已经存在的处理程序。如果您想要控制的处理程序的数量是有限的、恒定的,并且您知道这些处理程序的数量,那么您只需在pre函数中进行预验证之后,在If-else中调用它们即可。如果您想要更灵活的东西,您可以在删除之前获取所有处理程序,保存它们,然后在循环中调用它们

对于$(document.ready()结尾的“灵活”解决方案;将所有已存在的处理程序保存到数组中并禁用它们。然后编写pre函数并将其作为唯一的处理程序

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();
  });
请尝试console.log($。#u data($(“#abcd”)[0],“events”))查看它是什么

最后,只需运行post函数并使用条件执行您需要的任何操作

因此,一般算法如下:

  • 禁用onclick

  • 保存所有处理程序

  • 禁用所有处理程序

  • 先运行pre-func

  • 运行要执行的处理程序

  • 运行post func

  • 事实上,您只需要将pre-func作为唯一的处理程序,它可以运行您可能需要的所有其他处理程序。

    虽然非常正确,但我只想添加更多细节,以涵盖某些尚未解决的情况

    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);}
    }
    
    这或多或少地解决了所有的问题

    如果我错过了什么,请告诉我

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