5

我有一个按钮,它已经有一个 onclick 事件和一个分配的功能。我希望在它前面添加另一个函数调用。我可以想象应该可以摆弄 onclick 属性 ( attr),但我认为这不是最佳实践。

您认为在现有 onclick 事件上添加函数调用的最佳实践是什么?

4

6 回答 6

10

如果你不怕弄乱 jQuery 的胆量:

// "prepend event" functionality as a jQuery plugin
$.fn.extend({
  prependEvent: function (event, handler) {
    return this.each(function () {
      var events = $(this).data("events"), 
          currentHandler;

      if (events && events[event].length > 0) {
        currentHandler = events[event][0].handler;
        events[event][0].handler = function () {
          handler.apply(this, arguments);
          currentHandler.apply(this, arguments);
        }      
      }
    });
  }
});

$("#someElement").prependEvent("click", function () {
    whatever();
});​

现场观看:http: //jsfiddle.net/Tomalak/JtY7H/1/

请注意,必须已经存在 a currentHandler,否则该函数将不会执行任何操作。

免责声明:我认为这是一种黑客行为。这取决于可能在库的下一个版本中更改的 jQuery 内部结构。它现在可以工作(我测试了 jQuery 1.7.2),但如果它与 jQuery 的未来版本中断,请不要感到惊讶。

于 2012-04-16T07:07:38.077 回答
6

我在这里写了一个简短的例子

​$("button").click(function() { // this is already existing
    if ($("span").length) {
        alert("ok");
    }
});

var clicks = $("button").data("events").click.slice();
$("button")
    .unbind("click")
    .click(function() { // this is the new one which should be prepended
        $("body").append($("<span>"));
    });
$.each(clicks, function(i, v) {
    $("button").click(v);
});

​</p>

于 2012-04-16T06:52:18.693 回答
2

我认为没有办法在现有的 onclick 事件上预先调用函数,但是你可以试试这个:

$('#foo').unbind('click');
$('#foo').click(function() { 
   // do new function call..
   // call original function again...
});

希望有帮助。

于 2012-04-16T06:43:53.490 回答
1

您可以在单个事件上添加功能,但我尽量避免在 onclick 事件上使用两个功能。相反,您可以
1. 在现有函数中添加新代码。
2.从现有函数中添加对新函数的调用。

于 2012-04-16T06:41:59.273 回答
0

这似乎适用于 1.9.1 到 3.1.4。对于 1.9.1 之前的版本,请参阅Tomalak 的精彩回答

$(function() {
  $("input" ).mousedown( function() {
    console.log( "mousedown" );
  });

  $("input" ).click( function() {
    console.log( "click" );
  });
    
  $.fn.extend({exposeListeners: 
      function (fn) {
        return $._data( this[0], "events") || {};
      },
    prependListener: function (types, fn) {
      var elems = this;
      $(elems).each(function() {
        var elem = this;
        var $elem = $(elem)
        $elem.on(types, fn);

        var events = $._data( $elem[0], "events")[types];

        if (events.length > 1) { // its the only event, no reason to shift
            events.unshift(events.pop());  // put last as first
        }
    
        return this;
      });
    }
  })
  
  $("#prep").click(function () {
    console.log($("input").exposeListeners());
    $("input:not(:last)").prependListener("click", function () {
      console.log('click, prepended');
    })
    $("a").prependListener("click", function () {
      console.log('click event created');
    })
    console.log($("body").exposeListeners());
  })
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" value="input, Will accept prepend"><br>
<input type="button" value="input, Will also accept prepend"><br>
<input type="button" value="input, Will not"><br>
<a href="#">Link with no pre-exting handlers</a><br><br>

<Button id="prep">Prepend an event</Button>

这是一个准系统版本

$(function() {
  $.fn.extend({prependListener: function (types, fn) {
      var elems = this;
      $(elems).each(function() {
        var elem = this;
        var $elem = $(elem)
        $elem.on(types, fn);

        var events = $._data( $elem[0], "events")[types];

        if (events.length > 1) {
          events.unshift(events[events.length-1]);
          events.pop();
        }
    
        return this;
      });
    }
  })
})
于 2020-03-29T18:24:26.243 回答
-2

如果您已像这样绑定事件

$(elem).on('click', functionName);

你可以这样修改:

$(elem).on('click', function(){

 anotherFunctionNameOrWhateverYouWant();

 functionName();
});
于 2012-04-16T06:42:41.467 回答