2011-09-10 53 views
7

Dấu trang của tôi bao gồm lệnh gọi đến tập lệnh 'trình chạy' được chèn vào body. Khi nó chạy, nó chèn vào một cách tương tự như nhiều kịch bản lệnh (jQuery, ứng dụng thực tế) và một CSS.Làm cách nào để thực thi một bookmarklet chỉ chạy một lần?

Bookmarklet

javascript:(function(){ 
    var l = document.createElement('script'); 
    l.setAttribute('type','text/javascript'); 
    l.setAttribute('src','launcher.js'); 
    document.body.appendChild(l); 
})(); 

Launcher.js

var s = document.createElement('script'); 
s.setAttribute('type','text/javascript'); 
s.setAttribute('src','my actual script'); 
document.body.appendChild(s); 

// I repeat a block like this once per script/css. 

Vấn đề là nếu bookmarklet được nhấp hai lần, tất cả các kịch bản sẽ được chèn vào một lần nữa. Làm thế nào tôi có thể ngăn chặn hành vi này?

Trả lời

4

Bạn có thể đặt thuộc tính trên đối tượng window được đặt tên kỳ lạ, vì vậy không gây ra xung đột không gian tên . Trên chạy tiếp theo, mã sẽ không thực hiện nếu tài sản là hiện tại:

javascript:(function(){ 
     // Test for existence of your weird property 
     if (!window.hasOwnProperty('yourWeirdPropertyX774x9ZZYy4')) { 

      // Run all your existing code 
      var l = document.createElement('script'); 
      l.setAttribute('type','text/javascript'); 
      l.setAttribute('src','launcher.js'); 
      document.body.appendChild(l); 

     // Set the flag so this won't run again 
     window.yourWeirdPropertyX774x9ZZYy4 = true; 
     } 
    })(); 
+0

oops - được chỉnh sửa để sửa lỗi cú pháp thắng và đặt khối if từ fon anon thay vì vô nghĩa xung quanh nó. –

+0

Hoàn hảo - những nỗ lực trước đây của tôi chắc chắn nằm dọc theo những dòng này nhưng tôi đã sử dụng các biến thay vì đạo cụ cửa sổ, điều mà tôi hoàn toàn không biết. Cảm ơn! – vemv

+1

@vemv Một biến được khai báo bên trong một hàm là 'yourVar = 1234;' mà không có từ khóa 'var' ở trước nó thực tế trở thành thuộc tính của đối tượng' window' toàn cục, nhưng phương thức này rõ ràng hơn và có chủ ý. –

0

Simplest/Cleanest way to implement singleton in JavaScript?

Ví dụ về cách tốt để triển khai Singletons trong JS. Tôi sẽ không sao chép/dán câu trả lời của anh ấy, nhưng hãy đọc câu trả lời của anh ấy :)

+0

Có thể sử dụng từ 'singleton' là một sai lầm của tôi - tôi không nghĩ rằng việc đưa ứng dụng vào một đối tượng theo nghĩa đen sẽ giải quyết vấn đề này. – vemv

3

tôi thấy cách sạch cho tôi để làm điều này là để đặt tên cho chức năng đó tải các tập tin js bên ngoài, cùng tên với một chức năng bên trong tệp bên ngoài mà tôi muốn được chạy mỗi khi người dùng nhấp vào bookmarklet. Bằng cách này khi bookmarklet được nhấp vào lần đầu tiên, nó sẽ tải các tập tin bên ngoài và trên các nhấp chuột subsquent một chức năng trong tập tin bên ngoài được chạy.

Dưới đây là một số mã sudo:

Đây sẽ là mã trong url của liên kết bookmarklet

if(! bookmarklet){ 
    var bookmarklet = { 
    click: function(){ 
     js = document.createElement('SCRIPT'); 
     js.type = 'text/javascript'; 
     js.src = 'http://external.js?' + (Math.random()); 
     document.getElementsByTagName('head')[0].appendChild(js); 
    } 
    }; 
} 
bookmarklet.click(); // this will be called everytime the bookmarklet is clicked 

File external.js sẽ chứa một hàm có cùng tên như thế này:

var bookmarklet = { 
    click:function(){ 
     // insert logic you want to run every time the bookmarklet is clicked 
    } 
}; 
bookmarket.click(); // run once after file is loaded 

Cách này khi tệp bên ngoài được tải chức năng của bạn (ví dụ chức năng là bookmarklet.click) hiện đang chạy hàm bên trong tệp được tải bên ngoài và sẽ không lo quảng cáo tệp js bên ngoài lần thứ hai.

+0

Tôi mất một thời gian để hiểu nó (tên 'click' đánh lừa tôi) nhưng bây giờ tôi làm. Cách tiếp cận tốt đẹp, chúc mừng! – vemv

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