第一次调用时,ALSO运行jQuery事件处理程序

时间:2016-04-10 10:51:51

标签: jquery jquery-events

除了on之外,我需要在调用change时运行一次事件处理程序。我有一个<select>,可以在更改时更改页面的行为。它还为该按钮设置了一个默认值,这就是change处理程序应该在实际change发生之前第一次运行的原因。

示例(实际代码要复杂得多):

<select id="sel"><option>A<option>B<option>C</select>
<a id="go" href="#">Go</a>
<script>
    var base = "/act/";
    function update_go(){
        $('#go').prop('href',base+$(this).val());
    }
    $('#sel')
        .on('change',update_go) // update button when select is changed
        .each(update_go); // update button with the default value of the select 
    // todo: check: when select value is remembered by browser, does it work as it should?
</script>

我想扩展jQuery事件,在调用.on时允许一次运行的事件。这样我可以省略.each并使用内联匿名函数。这样的事情:

    $('#sel').on('change runonce',function(){
            $('#go').prop('href',base+$(this).val());
    });

我不想调用.trigger('change'),因为它可能会运行我不知道的事件处理程序。此外,当涉及到许多元素时,调用trigger的成本非常高;这就是为什么我不想打电话给trigger('runonce')

使用each或函数调用的速度要快得多,看起来不错,但它需要为每个事件都有一个命名函数。

谢谢

的jsfiddle: https://jsfiddle.net/oriadam/Lu9ym1xy/13/

JSPerf: http://jsperf.com/jquery-custom-trigger-vs-each-vs-function-call1

2 个答案:

答案 0 :(得分:1)

更新回答:

您可以创建自定义事件以满足您的需求:

(function() {
  var originalJqOn = jQuery.fn.on;
  jQuery.fn.extend({
    onAndFirst: function(evtName, fn) {
      fn();
      this.on(evtName, fn);
    }
  });
})();

var base = "/act/";
var update_go = function() {
  // in first run "this" equals the global window object
  if (this === window) {
    $('#go').prop('href', base + $("#sel").val());
    console.log("href set to: " + $("#sel").val());
  } else {
    $('#go').prop('href', base + $(this).val());
    console.log("href changed to: " + base + $(this).val());
  }
};

$('#sel').onAndFirst('change', update_go);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="sel"><option>A<option>B<option>C</select>
<a id="go" href="#">Go</a>

这是一个JsFiddle:https://jsfiddle.net/2zg8dgf4/2/

JsBin(查看日志):http://jsbin.com/wetocayala/1/edit?html,js,console,output

资源:https://learn.jquery.com/plugins/basic-plugin-creation/

这里有一个窗口对象的问题(请参阅我的解决方案中的评论)你应该考虑它的处理(这实际上取决于你将如何在你正在处理的实际案例中使用它,向上给你)。

原始回答:

我会使用函数调用,稍作修改:

// function
var first_and_change_call=function(){
   update_selected(this);
}.call($('#sel_call')[0]);

更新小提琴:https://jsfiddle.net/Lu9ym1xy/14/

如果您需要更复杂的内容,请提供更多详细信息。

答案 1 :(得分:0)

更新:更优雅的答案

// call the handler now and on events //
jQuery.fn.extend({
  onAndNow: function(events, func) {
    return this.each(func).on(events, func);
  }
});
// TODO: Support the data object
///////////////////////////////////

// usage example:
$('#select').onAndNow('change', function() {
  var val = $(this).val();
  $('#go').prop('href', '//example.com/?' + val).html('Go to ' + val);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="select">
    <option>save a life</option>
    <option>eat spaghetti</option>
</select>
<a id="go" target="_blank">Go nowhere?</a>

https://jsfiddle.net/oriadam/v91wepuk/