[英]Click events from two scripts on same element?
编辑:我想我已经解决了! 我想尝试自己解决此问题,然后再寻求更多帮助=)
第一个脚本禁止第二个脚本用作第一个脚本的单击事件,从而覆盖第二个脚本。 由于第二个脚本不起作用,因此无法打开下拉菜单以选择列表项来触发第一个脚本单击。
我试图用event.stopPropagation()替换所有返回的false语句。 但是没有工作。 尝试重新排序我的脚本,但是也失败了。 我当时想让我的第二个脚本针对另一个父div,但这也没有用。我还尝试了event.stopImmediatePropagation()和.bind方法。
任何想法?
第一个执行下拉功能的脚本。 包含点击事件。
function DropDown(el) {
this.f = el;
this.placeholder = this.f.children('span');
this.opts = this.f.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents : function() {
var obj = this;
obj.f.on('click', function(event){
$(this).toggleClass('active');
return false;
});
obj.opts.on('click',function(){
var opt = $(this);
obj.val = opt.text();
obj.index = opt.index();
obj.placeholder.text(obj.val);
});
},
getValue : function() {
return this.val;
},
getIndex : function() {
return this.index;
}
}
$(function() {
var f = new DropDown( $('#f') );
$(document).click(function() {
// all dropdowns
$('.filter-buttons').removeClass('active');
});
});
第二个脚本进行过滤,还包含click事件:
jQuery(document).ready(function(e) {
var t = $(".filter-container");
t.imagesLoaded(function() {
t.isotope({
itemSelector: "figure",
filter: "*",
resizable: false,
animationEngine: "jquery"
})
});
$(".filter-buttons a").click(function(evt) {
var n = $(this).parents(".filter-buttons");
n.find(".selected").removeClass("selected");
$(this).addClass("selected");
var r = $(this).attr("data-filter");
t.isotope({
filter: r
});
evt.preventDefault();
});
$(window).resize(function() {
var n = $(window).width();
t.isotope("reLayout")
}).trigger("resize")
});
html结构
<div id="f" class="filter-buttons" tabindex="1">
<span>Choose Genre</span>
<ul class="dropdown">
<li><a href="#" data-filter="*" class="selected">All</a></li>
<li><a href="#" data-filter=".electronic">Electronic</a></li>
<li><a href="#" data-filter=".popular">Popular</a></a></li>
</ul>
</div>
这并不能真正解决您的问题,但是我在喝咖啡时很无聊,感觉就像是在帮助您更好地编写下拉插件
我在下面的评论与代码一致。 有关不间断的代码,请参见DropDown完整粘贴 。
我们从您的标准jQuery包装器开始(function($){ ... })(jQuery)
(function($) {
// dropdown constructor
function DropDown($elem) {
首先,我们将创建一些私有变量来存储信息。 通过使用this.foo = ...
我们(可能)不必要地暴露了事物。 如果您需要访问这些变量,则始终可以创建函数来读取它们。 这是更好的封装imo。
// private vars
var $placeholder = $elem.children("span");
var $opts = $elem.find("ul.dropdown > li")
var value = "";
var index = -1;
现在,我们将定义事件监听器以及这些事件监听器可能依赖的功能。 这里的obj.f.*
是,这些函数不必通过this.*
或在编写obj.f.*
等时访问所有内容。
// private functions
function onParentClick(event) {
$elem.toggleClass("active");
event.preventDefault();
}
function onChildClick(event) {
setValue($(this));
event.preventDefault();
}
function setValue($opt) {
value = $opt.text();
index = $opt.index();
$placeholder.text(value);
}
这是一些属性描述符,用于读取index
和value
// properties for reading .index and .value
Object.defineProperty(this, "value", {
get: function() { return value; }
});
Object.defineProperty(this, "index", {
get: function() { return index; }
});
最后,让我们跟踪数组中每个DropDown
实例,以便用户不必定义特殊的侦听器即可停用每个
// track each instance of
DropDown._instances.push(this);
}
这是我们用来跟踪实例的数组
// store all instances in array
DropDown._instances = [];
此事件侦听器停用DropDown的每个“已注册”实例
// deactivate all
DropDown.deactiveAll = function deactiveAll(event) {
$.each(DropDown._instances, function(idx, $elem) {
$elem.removeClass("active");
});
}
这是插件中定义的文档监听器! 用户不再需要设置它
// listener to deactiveAll dropdowns
$(document).click(DropDown.deactiveAll);
最好将其设为jQuery插件,因为DropDown构造函数中的所有内容都依赖jQuery。 这让用户执行var x = $("foo").dropdown();
// jQuery plugin
$.fn.dropdown = function dropdown() {
return new DropDown($(this));
};
关闭包装纸
})(jQuery);
现在这是你的用法
$(function() {
var x = $('#f').dropdown();
// get the value
f.value;
// get the index
f.index;
});
不管怎样,是的,我知道这对您的点击侦听器并没有真正帮助,但是我希望这对您仍然有用。 现在去邮局!
我认为您将需要简化此过程以弄清楚发生了什么。 实际上,没有足够的信息来查看事件在此处附加的元素。
为了论证,打开控制台并尝试以下操作:
$(document).on('click', function() { console.log('first'); return false; });
$(document).on('click', function() { console.log('second'); return false; });
然后单击页面。 您会看到两个事件都被触发。 很有可能您的代码实际上是将事件附加到不同的元素上(您在任何地方都没有说)。 如果真是这样,那么您需要了解事件冒泡在DOM中的工作方式。
当您触发事件时,例如单击某个元素,则该事件将在该元素上触发,然后在其父元素上触发,然后在祖父母,外祖父母等一直指向顶部的根节点。
您可以通过在事件本身中调用函数来更改此行为。 evt.stopPropagation
告诉事件不冒泡到祖先节点。 evt.preventDefault
告诉浏览器不要对节点执行默认行为(例如,移动到href中为A标签指定的页面)。
在jQuery中,从事件处理程序return false
是evt.preventDefault
和evt.stopPropagation
的快捷方式。 这样一来,事件就不会停止。
我想你有这样的事情:
<div event_two_on_here>
<a event_one_on_here>
</div>
如果处理event_one_on_here
的事物调用stopPropagation
则event_two_on_here甚至都不会知道它已发生。 显式或隐式调用stopPropagation
( return false
)将在事件传播到父节点/事件处理程序之前终止该事件。
更新:在您的情况下,问题是.filter-buttons a
上的处理程序正在停止传播(因此#f
无法运行其处理程序)。
$(".filter-buttons a").click(function(evt) {
// your code here...
// Don't do this - it stops the event from bubbling up to the #f div
// return false;
// instead, you'll probably just want to prevent the browser default
// behaviour so it doesn't jump to the top of the page ('url/#')
evt.preventDefault();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.