2010-02-17 35 views
9

Vì vậy, tôi đang cố gắng tải một tập lệnh động và tìm ra đường dẫn URL mà tập lệnh được tải. Vì vậy, một số người đã cho tôi một giải pháp khá tuyệt vời cho vấn đề này nếu các kịch bản được tải tĩnh (How to get the file-path of the currently executing javascript code). Nhưng tôi cần một giải pháp tự động nạp. Ví dụ:Nhận url của tệp js hiện đang thực thi khi được nạp động

$(function() 
{ $.getScript("brilliant.js", function(data, textStatus) 
    { // do nothing 
    }); 
}); 

nơi "brilliant.js" có:

var scripts = document.getElementsByTagName("script"); 
var src = scripts[scripts.length-1].src; 
alert("THIS IS: "+src); 

Lý tưởng này nên hoặc in ra "brilliant.js" hoặc "⟨ hostname + basepath ⟩ /brilliant.js"

Hiện tại, tệp brilliant.js hoạt động cho các tập lệnh được bao gồm tĩnh, nhưng không phải cho các tập lệnh được bao gồm động (như với $ .getScript). Ai có ý tưởng gì không? Có nơi nào đó trong nhà kho lưu trữ tất cả các tập lệnh đã được tải không?

EDIT: Andras đưa ra một giải pháp khá tốt, mặc dù nó có thể chỉ hoạt động cho jQuery. Vì đó có lẽ là thư viện phổ biến nhất, và chắc chắn những gì tôi sẽ sử dụng. Nó có thể được mở rộng cho các thư viện khác. Đây là phiên bản đã được đơn giản hóa của tôi:

var scriptUri; 
curScriptUrl(function(x) 
{ scriptUri = x; 
    alert(scriptUri); 
}); 

function curScriptUrl(callback) 
{ var scripts = document.getElementsByTagName("script"); 
    var scriptURI = scripts[scripts.length-1].src; 

    if(scriptURI != "")   // static include 
    { callback(scriptURI); 
    }else if($ != undefined) // jQuery ajax 
    { $(document).ajaxSuccess(function(e, xhr, s) 
     { callback(s.url); 
     }); 
    } 
} 
+0

Tôi thích những gì chamiltongt (bên dưới) cho biết, ajax trong mã, và sau đó eval() nó. Để làm cho nó có thể truy cập trên toàn cầu, tại sao bạn không thiết lập một trang web nhỏ gọn phục vụ mã .js của bạn. Nó sẽ được tập trung và bạn có thể cập nhật mã của bạn cho mọi người dùng ngay lập tức. – logout

Trả lời

8

Khi tập lệnh của bạn được tải bằng jQuery (và tôi cũng đoán các khung công tác khác), tập lệnh của bạn sẽ không thể phân biệt được với tập lệnh ban đầu trong tài liệu HTML.

jQuery thực hiện yêu cầu liên hệ với tập lệnh của bạn và gửi trả lời dưới dạng văn bản của nút tập lệnh >. Trình duyệt của bạn không có cách nào để biết nó bắt nguồn từ đâu, cho dù nó đã được sửa đổi trước khi chèn, vv Nó chỉ là một nút kịch bản như xa như cô ấy là có liên quan.

Có thể có cách giải quyết khác. Trong trường hợp của jQuery, bạn có thể kết nối với các sự kiện ajax và khai thác thực tế là chúng được gọi ngay sau khi kịch bản của bạn thực thi. Về cơ bản, điều này sẽ mang lại "brilliant.js" trong ví dụ của bạn:

var handler = function (e, xhr, s) { 
    alert(s.url); 
} 

$(document).ajaxSuccess(handler); 

Một phức tạp hơn một:

(function ($, undefined) { 

    /* Let's try to figure out if we are inlined.*/ 
    var scripts = document.getElementsByTagName("script"); 

    if (scripts[scripts.length - 1].src.length === 0) { 
     // Yes, we are inlined. 
     // See if we have jQuery loading us with AJAX here. 
     if ($ !== undefined) { 
      var initialized = false; 
      var ajaxHandler = function (e, xhr, s) { 
       if (!initialized) { 
        initialized = true; 
        alert("Inlined:" + s.url); 
        initmywholejsframework(); 
       } 
      } 

      //If it is, our handler will be called right after this file gets loaded. 
      $(document).ajaxSuccess(ajaxHandler); 

      //Make sure to remove our handler if we ever yield back. 
      window.setTimeout(function() { 
       jQuery(document).unbind("ajaxSuccess", ajaxHandler); 
       if (!initialized) { 
        handleInlinedNonjQuery(); 
       } 
      }, 0); 

     } 
    } else { 
     //We are included. 
     alert("Included:" + scripts[scripts.length - 1].src); 
     initmywholejsframework(); 
    } 

    //Handle other JS frameworks etc. here, if you will. 
    function handleInlinedNonjQuery() { 
     alert("nonJQuery"); 
     initmywholejsframework(); 
    } 

    //Initialize your lib here 
    function initmywholejsframework() { 
     alert("loaded"); 
    } 

})(jQuery); 
+0

Giải pháp thay thế tuyệt vời. Tôi muốn một cách phổ biến hơn để giải quyết vấn đề này - nhưng có vẻ như đây chỉ là điều tốt nhất có. Tôi đã chỉnh sửa câu hỏi của mình ở trên để hiển thị phiên bản của tôi về những gì bạn đã viết. –

-1

B T, xin lỗi nếu điều này không hữu ích, nhưng tôi rất tò mò tại sao bạn cần làm điều này? Lý do tôi hỏi là tôi không thấy lý do tại sao bạn không thể chỉ sử dụng đường dẫn tệp tương đối để tải các tệp này? Tìm ra nơi bạn đang ở có thể được thực hiện với window.location, nhưng tại sao bạn? Và như để tải chúng, bạn không thể thực hiện một cuộc gọi ajax đến tập tin và sau đó đánh giá chúng?

+0

Ngoài ra, tôi chỉ nhớ một cách dễ dàng hơn, bạn có thể thêm các phần tử tập lệnh vào trang động. Dưới đây là liên kết đến cách thực hiện việc này -> http://www.codehouse.com/javascript/articles/external/ – chamiltongt

+0

Tôi đang tạo thư viện javascript có nghĩa là được tải bởi miền bên ngoài. Đây không phải là câu hỏi về các tệp javascript đơn giản. Xem liên kết sau nếu bạn muốn có thêm ngữ cảnh, cảm ơn: http: // stackoverflow.com/questions/2255689/how-to-get-the-file-đường dẫn-of-the-currenctly-thi hành-javascript-code. –

+0

+1 cho ý tưởng ajax và eval() :) – logout

-1

này sẽ làm việc ở mọi trình duyệt trừ IE và không phụ thuộc vào giả định gì tên của một tệp là:

var getErrorLocation = function (error) { 
    var loc, replacer = function (stack, matchedLoc) { 
     loc = matchedLoc; 
    }; 

    if ("fileName" in error) { 
     loc = error.fileName; 
    } else if ("stacktrace" in error) { // Opera 
     error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer); 
    } else if ("stack" in error) { // WebKit 
     error.stack.replace(/at (.*)/gm, replacer); 
     loc = loc.replace(/:\d+:\d+$/, ""); // remove line number 
    } 
    return loc; 
}; 

try { 
    0(); 
} catch (e) { 
    var scriptURI = getErrorLocation(e); 
} 

alert("THIS IS: " + scriptURI); 
+0

Ông đang tải tập lệnh với $ .getScript() tương đương với việc thêm một thẻ