[英]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.