2012-01-30 39 views
9

Vì vậy, tôi đang sử dụng điện thoại di động Jquery với thành công lớn ngoại trừ một vấn đề. Bây giờ mỗi khi trang nội dung động được điều hướng đến bởi người dùng bất kể nội dung nào hiển thị, luôn có nút ở phía dưới khi nhấp vào email nội dung đến địa chỉ được chỉ định; hoạt động tốt. Bây giờ, lần đầu tiên trang được tải, nhấp chuột sẽ kích hoạt sự kiện một lần. Trong lần truy cập thứ hai của nó bị bắn hai lần, thứ ba 3 lần, vv bạn có được điểm. Tôi đã quét lưới và thực hiện mọi sửa chữa mà tôi có thể gặp phải, chẳng hạn như sử dụng "pagecreate" thay vì "pageinit", ràng buộc, unbinding, xóa div, tắt bộ nhớ đệm trong DOM nhưng không có gì hoạt động. Thành công duy nhất tôi có là sử dụng .one() khi nhấp chuột nhưng nó cần phải được kích hoạt nếu được nhấp lại. Đây là cấu trúc. Tôi phải .js file tải mỗi này để bắt đầuDi động Jquery. Nhấp nhiều lần vào lần truy cập trang mới

$("#page").live("pageinit", function() { 

Bây giờ tôi đã có chức năng email và các công cụ khác trong một tập tin, nhưng nó làm cho nó dễ dàng hơn để tách họ và tôi nghe nói nó không quan trọng. Bây giờ, đây là chức năng email gọi trong pageinit

$('.eb').live('click', function() { 
     var id = $('.eb').attr('id'); 
     var to = $('#recipient').val(); 
     var message = $('#email').html(); 

     var atpos = to.indexOf("@"); 
     var dotpos = to.lastIndexOf("."); 
     if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     if(to.length == 0) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     $.mobile.showPageLoadingMsg(); 

     $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) { 
      if(data.success == true) { 
       $.mobile.hidePageLoadingMsg(); 
       alert('Your recipe has been sent!'); 
       $('#recipient').val(''); 
       return true; 
      } 

      if(data.success == false) { 
       if(data.fail == 1) { 
        alert('An error has occured sending your recipe. Try again soon!'); 
        return false; 
       } 

       if(data.fail == 2) { 
        alert('Please enter a valid email address!'); 
       } 
      } 
     }, 'json'); 
      return false; 
    }); 

Tất cả mọi thứ hoạt động hoàn hảo, ngoại trừ việc sa thải gia tăng của .click trên mỗi trang mới. Có ai có thể dẫn tôi đi đúng hướng không?

Trả lời

2

tôi giải quyết điều này bằng cách nhận ra vấn đề là với div bản thân, #page. Trang này được tải với nội dung động nhưng id không bao giờ làm, vì vậy một nơi nào đó dọc theo dòng nó được lưu trữ ở đâu đó và được tăng lên từng lượt truy cập mới một. Tôi vừa thêm một số mã PHP để tạo một id div duy nhất trên mỗi lần tải trang.

<?php $id = uniqid() ?> 
<div id="<?php echo $id; ?>">CONTENT</div> 

Điều này giải quyết được sự cố và chỉ xảy ra khi tải lại trang.

+4

Quá trình này được để lại đằng sau tất cả các loại sự kiện ràng buộc không cần thiết (người dùng trang web của bạn nhận được càng nhiều, trình duyệt sẽ chậm hơn vì bạn chỉ tải trình xử lý sự kiện được ủy quyền nhiều hơn và nhiều hơn nữa. bong bóng lên DOM). Vấn đề của bạn là một cạm bẫy thường xuyên khi làm việc với nội dung động, bạn đã quá tự do với sự ràng buộc sự kiện của bạn. Bản sửa lỗi thực sự là ngừng sử dụng trình xử lý sự kiện được ủy quyền, nơi chúng không cần thiết. Tôi rất vui vì bạn đã tìm ra điều gì đó nhưng đây không phải là câu trả lời hay. – Jasper

13

Kể từ jQuery 1.7, phương pháp .live() không còn được dùng nữa. Sử dụng .on() để đính kèm trình xử lý sự kiện.

Nếu bạn đang sử dụng 1,7+ cố gắng hủy liên kết sự kiện nhấp bằng cách sử dụng .off() trước tiên.

$('.eb').off('click').on('click', function() { 
// ... 
}); 

nếu bạn phải sử dụng .live() bạn có thể unbind các sự kiện với .die()

$('.eb').die('click').live('click', function() { 
// ... 
}); 

hoặc sử dụng tốt hơn .delegate().undelegate() un các yếu tố phụ huynh:

$(document).undelegate('.eb', 'click').delegate('.eb', 'click', function() { 
// ... 
}); 
+0

jQuery Mobile vẫn đi kèm với jQuery Core 1.6.4, không có '.on()', nhưng '.delegate()' vẫn được ưu tiên hơn '.live()'. – Jasper

+0

Tôi đã chỉnh sửa câu trả lời của mình và thêm một ví dụ cho '.delegate()' – Ingemar

+1

Ok, một vài vấn đề. ** 1) ** '$ ('. Eb'). On ('click'' không giống với' .live() ',' $ (document) .on (' click ',' .eb ') , function() {...}) 'cũng giống như' .live() '. Cách bạn đang sử dụng' .on() 'giống như' .bind() '. ** 2) * * Cũng trong jQuery Mobile, bạn thường ủy nhiệm các sự kiện từ phần tử 'document' vì nó là phần tử ** only ** được bảo đảm trong DOM tại bất kỳ thời điểm nào. – Jasper

10

Đơn giản chỉ cần di chuyển các sự kiện click mã trình xử lý bên ngoài mã số xử lý sự kiện pageinit như sau:

$(document).delegate("#page", "pageinit", function() { 


}); 
$(document).delegate('.eb', 'click', function() { 
     var id = $('.eb').attr('id'); 
     var to = $('#recipient').val(); 
     var message = $('#email').html(); 

     var atpos = to.indexOf("@"); 
     var dotpos = to.lastIndexOf("."); 
     if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     if(to.length == 0) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     $.mobile.showPageLoadingMsg(); 

     $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) { 
      if(data.success == true) { 
       $.mobile.hidePageLoadingMsg(); 
       alert('Your recipe has been sent!'); 
       $('#recipient').val(''); 
       return true; 
      } 

      if(data.success == false) { 
       if(data.fail == 1) { 
        alert('An error has occured sending your recipe. Try again soon!'); 
        return false; 
       } 

       if(data.fail == 2) { 
        alert('Please enter a valid email address!'); 
       } 
      } 
     }, 'json'); 
      return false; 
    }); 

Khi bạn sử dụng nhóm sự kiện bạn không muốn ràng buộc bên trong một trình xử lý sự kiện khác, vì mỗi lần xử lý sự kiện bạn sẽ ràng buộc lại (và khi bạn ủy quyền xử lý sự kiện họ được ủy nhiệm cho cuộc sống của DOM).

Bạn cũng có thể sử dụng .bind() thay vì .live() (đây là phương pháp ưa thích của tôi):

$(document).delegate("#page", "pageinit", function() { 
    $('.eb').bind('click', ...); 
}); 

Bạn sẽ thấy rằng cả hai ví dụ của tôi thay đổi-out .live() cho .delegate() như nó thực hiện nhanh hơn một chút ngay cả khi ủy thác từ phần tử document. .delegate() s sức mạnh thực sự là bạn có thể chọn phần tử gốc thay vì phải liên kết với các yếu tố document: http://api.jquery.com/delegate

+0

Tôi đã thử cả giải pháp Ingemar và cả hai đều ngăn chặn đám cháy đa dạng thật tuyệt vời. Vấn đề là hành vi quá rời rạc mà tôi không hiểu. Tôi nhấp vào nó nếu cháy, nhấp vào nó một lần nữa không có gì, nhấp vào nó 3 lần nó cháy, nhấp vào nó một khi nó cháy .. etc, Đó là hành vi kỳ lạ. – Naterade

+0

Đoạn mã trên sẽ không kích hoạt bất kỳ đám cháy nào và nếu nó được đặt trong phạm vi toàn cục, nó sẽ có sẵn cho mọi sự kiện 'click' được kích hoạt trên các phần tử' .eb'. Nếu bạn vẫn gặp sự cố thì có thể bạn đã đăng bản sửa lỗi của mình trong phạm vi sai hoặc có lỗi ở nơi khác trong mã của bạn. Để kiểm tra lỗi, hãy mở bảng điều khiển delevoper của bạn (hầu như luôn luôn là 'F + 12'). – Jasper

+0

Bạn đã lưu tôi giờ! Cảm ơn bạn! – Michal

0

Nếu bạn nghi ngờ rằng biểu mẫu (ví dụ: biểu mẫu bật lên) đang tạo nhiều trang khi bạn gửi thử thêm dữ liệu-ajax = "false" vào phần tử biểu mẫu của từng biểu mẫu. Điều này giải quyết được vấn đề của tôi.

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