2010-10-16 20 views
5

vì vậy tôi có thẻ neo theo hình thức <a href='[link'] rel='Tab'> và tôi áp dụng sau tại tải trang :('tài liệu sẵn sàng' Tôi có nghĩa)Cách liên kết hàm với các sự kiện DOM một lần và chỉ một lần để chúng không thực thi lần thứ hai trong khi kích hoạt sự kiện?

jQuery("a[rel*=Tab]").click(function(e) { 
       e.preventDefault();//then I do some stuff to open it in jq ui tab} 

bây giờ vấn đề là khi tôi làm điều này và sau đó thông qua javascript mới liên kết được tạo ra, trong trường hợp của tôi với tải một trang thứ hai với JqGrid có mới <a rel='neoTab'> 's không tồn tại khi tôi lần đầu tiên chạy jQuery("a[rel*=Tab]").click(function(e) để chúng không hoạt động ... vì vậy tôi có thể chạy jQuery("a[rel*=Tab]").click(function(e) tại mọi sự kiện tạo liên kết mới nhưng sau đó các liên kết cũ sẽ tải nhiều tab để có cách nào tôi có thể chọn tất cả "a[rel*=Tab]" không được chọn trước đó?

lưu ý: Tôi có thể giải quyết vấn đề này thông qua các chi tiết bên dưới, tôi chỉ nghĩ rằng có một số cú pháp mà tôi không biết.

chi tiết không cần thiết:

var neoTabitStat = 0; 
var openTabs = new Array(); 
openTabs[0] = 'inbox'; 
if(!(currentBox=='inbox'||currentBox=='outbox')) {var currentBox = 'inbox';} 

function initNeoTab(a){ 
    if(neoTabitStat==0) { 
     jQuery("a[rel*="+a+"]").click(function(e) { 
      e.preventDefault(); 
      tabIt(jQuery(this).attr('href')+'&nohead=1',jQuery(this).attr('title'),jQuery(this).attr('data-hovercard')); 
     }); 
    neoTabitStat++; 
    } 
} 

function tabIt(a,b,c) { 
    c = typeof(c) != 'undefined' ? c : 0; 
    lastOpen = openTabs.length; 
    if(lastOpen<6) { 
     if(openTabs.indexOf(c)<0) { 
      openTabs[lastOpen] = c; 
      jQuery("#tabs").tabs("add" , a , b, lastOpen+1); 
     } 
     $tabs.tabs('select', openTabs.indexOf(c)); 
    }else{ 
     var tabErrDig = jQuery('<div style="display:hidden">You have opened the maximum amount of tabs please close one to open another tab.</div>').appendTo('body'); 
     tabErrDig.dialog({width:500,title:'Maximum Tabs Opened',modal: true, 
       buttons: { 
        Ok: function() { 
         jQuery(this).dialog("close"); 
        } 
       } 
     }); 
    } 
} 

jQuery(document).ready(function() { initNeotab('nameOfrelAttr4existingLinks'); } 
myGrid = jQuery("#list").jqGrid({/*alot of stuff...*/} , gridComplete: function() { initNeotab('nameOfrelAttr4generatedLinks'); 
} 

UPDATE: như Wrikken gợi ý jQuery() sống tôi đã kiểm tra nó ra và nó là chính xác những gì tôi cần, nhưng tôi không thể làm cho nó thực sự làm việc. , nó sẽ không hoạt động trong một số trường hợp. Đối với những người khác đã viết các giải pháp khác nhau, bạn có quen thuộc với .live() nếu vậy tại sao tôi không thể sử dụng nó ở đây?

KẾT LUẬN đặc biệt nhờ fudgey, patrick dw và wrikken. Tất cả các câu trả lời đều hữu ích. .delegate(). đã làm việc cho tôi nhưng vì lý do nào đó, .live() thì không. một cái gì đó về cách jqGrid thêm các yếu tố vào bảng. Tôi sẽ tiếp tục mở câu hỏi trong một thời gian. Cảm ơn rất nhiều lần nữa vì sự giúp đỡ của bạn. 1 cho tất cả

+0

@patrick yes Tôi đã kết thúc bằng cách sử dụng ủy quyền cho bây giờ vì mọi thứ đã được thêm vào #list. vì đó là id của bảng mà jqGrid đang làm việc. Tôi nghĩ rằng sẽ có một giải pháp tốt hơn với các phương pháp trong jqGrid vì vậy tôi sẽ chờ đợi một số câu trả lời từ các chuyên gia jqGrid và trong khi đó nghiên cứu nó nhiều hơn bản thân mình, nhưng tôi đã có mã làm việc cho đến nay. – Neo

Trả lời

1

Tôi sẽ đề xuất sử dụng .one() nhưng có vẻ như bạn đang thêm liên kết động. Vì vậy, tôi có thể là tốt nhất để thêm một lá cờ vào một liên kết đã được nhấp vào. Như Patrick đề xuất, đại biểu sẽ là tốt nhất cho điều đó, với những sửa đổi này:

jQuery("#list").delegate('a[rel*=Tab]', 'click', function() { 

if ($(this).is('.alreadyClicked')) { return false; } 
$(this).addClass('alreadyClicked'); 

// do something 

}); 
+0

fudgey - Tôi nghĩ tiêu đề của câu hỏi có thể gây hiểu nhầm một chút. Bởi * "chỉ một lần" *, tôi nghĩ OP là đề cập đến thực tế là anh ta đang tìm kiếm toàn bộ DOM để tìm các phần tử '' mới được tạo và gán 'click'. Vì vậy, những cái cũ đang nhận được nhiều trình xử lý 'click' thay vì một. Tôi có thể sai, nhưng đó là những gì tôi nhận được từ cơ thể của câu hỏi. : o) – user113716

+0

có patrick bạn đúng nhưng fudgey là đúng cũng như anh ấy bằng tay làm điều đó. – Neo

2

"#list" các yếu tố có chứa các yếu tố tạo động <a>?

Nếu có, hãy sử dụng jQuery's .delegate() method để đặt trình xử lý lên đó, vì vậy, bất kỳ phần tử nào trong số 'a[rel*=Tab]' được nhấp vào trong đó sẽ kích hoạt trình xử lý.

jQuery("#list").delegate('a[rel*=Tab]', 'click', function() { 
    //... 
}); 

Mọi thành phần 'a[rel*=Tab]' được thêm vào #list sẽ tự động hoạt động. Nếu #list không phải là vùng chứa, hãy sử dụng bộ chọn chính xác cho vùng chứa.


EDIT: Trong khi phương pháp .delegate() trên là (theo ý kiến ​​của tôi) phương pháp tốt nhất, nếu bạn đã muốn gán cá nhân click xử lý để chỉ các yếu tố mới như bạn tạo ra chúng, bạn sẽ cần phải gọi phương thức .click() tương tự với các thành phần mới cụ thể.

Vì vậy, nếu bạn tạo một mới <a> sau khi tải trang, bạn muốn làm điều gì đó như thế này:

var $newA = $('<a rel="someTab">some text</a>'); 

// Assign click handler to only the newly created element 
$newA.click(function(e) { 
     e.preventDefault(); 
     //then I do some stuff to open it in jq ui tab 
}); 

$newA.appendTo('#list'); 

Tất nhiên đây không phải là mã chính xác của bạn, nhưng cho thấy làm thế nào bạn có thể tạo ra một nguyên tố mới, lưu trữ một tham chiếu đến nó và chỉ định trình xử lý click cho phần tử đó.

Hoặc nếu bạn đang tạo một cấu trúc lớn hơn nơi <a> được lồng nhau, bạn có thể làm điều tương tự, nhưng làm một .find() để có được những <a> bên trong cấu trúc, sau đó gán các click.

Các vấn đề liên quan