首先,这可能吗?我已经纠结了好几个小时了;我认为我的事件没有触发的原因是因为一个事件正在取消绑定/覆盖另一个。我想绑定两个change
事件到同一个元素。我该怎么做呢?
按照要求,这里的函数我挣扎:
(function($) {
$.fn.cascade = function(name, trigger, url) {
var cache = {};
var queue = {};
this.each(function() {
var $input = $(this);
var $trigger = $input.closest('tr').prev('tr').find(trigger);
//$input.hide();
var addOptions = function($select, options) {
$select.append('<option value="">- Select -</option>');
for(var i in options) {
$select.append('<option value="{0}">{1}</option>'.format(options[i][0], options[i][1]));
}
$select.val($input.val()).trigger('change');
}
var $select = $('<select>')
// copy classes
.attr('class', $input.attr('class'))
// update hidden input
.bind('change', function() {
$input.val($(this).val());
})
// save data for chaining
.data('name', name)
.data('trigger', $trigger);
$input.after($select);
$trigger.bind('change', function() {
var value = $(this).val();
$select.empty();
if(value == '' || value == null) {
$select.trigger('change');
return;
}
// TODO: cache should be a jagged multi-dimensional array for nested triggers
if(value in cache) {
addOptions($select, cache[value]);
} else if(value in queue) {
$select.addClass('loading');
queue[value].push($select);
} else {
var getDict = {}
getDict[name] = value;
// TODO: use recursion to chain up more than one level of triggers
if($(this).data('trigger')) {
getDict[$(this).data('name')] = $(this).data('trigger').val();
}
$select.addClass('loading');
queue[value] = [$select];
$.getJSON(url, getDict, function(options) {
cache[value] = options;
while(queue[value].length > 0) {
var $select = queue[value].pop();
$select.removeClass('loading');
addOptions($select, options);
}
});
}
}).trigger('change');
});
return this;
}
})(jQuery);
HTML的相关块甚至更长...但本质上它是一个带有一系列年份的选择框,然后一个<input>
被(明显地)替换为显示该年份车辆制造商的<select>
,然后另一个<input>
被替换为该制造商/年份的型号。
实际上,除了页面加载之外,它现在似乎运行得很好。初始值正在被擦除。
已通过取出$select.bind()
位并使其活动来解决问题:
$('select.province').live('change', function() {
$(this).siblings('input.province').val($(this).val());
});
$('select.make').live('change', function() {
$(this).siblings('input.make').val($(this).val());
});
$('select.model').live('change', function() {
$(this).siblings('input.model').val($(this).val());
});
糟糕的是,它是硬编码在那里的,虽然我的个别情况。理想情况下,我想封装所有的逻辑在那个函数。所以我可以有
$('input.province').cascade('country', 'select.country', '/get-provinces.json');
$('input.make').cascade('year', 'select.year', '/get-makes.json');
$('input.model').cascade('make', 'select.make', '/get-models.json');
3条答案
按热度按时间093gszye1#
是的,有可能。
jQuery事件绑定是附加的,第二次调用
.change
不会删除原始事件处理程序。tyu7yeag2#
Ryan认为jQuery是可添加的,这是正确的,尽管如果您发现链接同一个事件会出现问题,但漂亮的jQuery允许另一种方法,即在完成第一个函数后在第一个函数中调用第二个函数,如下所示。
我经常在表单验证中使用这种技术,一个函数用于检查和替换不允许的字符输入,第二个函数用于在父函数的结果上运行正则表达式。
更新至发布日期:
好吧......你们都很快就用你们的负分数来击败我,而不理解我们各自看待马克请求的不同之处。我将继续通过例子来解释为什么我的方法更好,因为它允许最大的灵活性和控制。我在下面的链接中给出了一个快速的例子。一张图片胜过1000个单词。
Nested Functions on One Event Trigger
此示例说明如何将三个函数仅绑定到一个更改事件,以及如何独立控制第二个和第三个函数,即使它们仍由父更改事件触发。此示例还说明如何通过编程将第二个和第三个函数都绑定到同一父函数触发器。但是响应或者独立于它嵌套的父函数(通过取消选中复选框可以看到这一点)。
我在示例中包含了第三个“Do thing #3”,以显示另一个事件如何跟随前面描述的两个嵌套函数。
请原谅前面最先发布的错误伪代码,因为我总是在jQuery中使用ID,因为它们能够为jQuery处理的所有内容提供单独的状态。我在自己的代码中从不使用'input:checkbox'方法,因为这依赖于输入语句的'type'属性,因此如果文档中有多个复选框,则需要额外的处理来隔离任何所需的复选框。希望这个示例能够成功地阐明我在这里的评论中没有的内容。
62lalag43#
实际上,我不确定是否可以绑定两个不同的更改事件。但是,为什么不使用逻辑来完成这两个事件呢?例如...
这样,你会得到同样的好处,现在,如果你需要做两件不同的事情,你可能需要使用逻辑,这样只有一件事情发生,但我认为你无论如何都要这样做,即使你可以把两个改变事件绑定到同一个元素。