2008-11-25 17 views
7

Với mục đích theo dõi tài liệu không phải HTML thông qua google analytics, tôi cần thuật toán được đề cập. Nó nên:Javascript: làm cách nào để xác định liệu một liên kết có nhắm mục tiêu tên miền giống với trang mà nó cư trú không?

  • không mã hóa cứng các miền
  • bỏ qua các giao thức (ví dụ: http/https)
  • không lo lắng về sự có mặt/vắng mặt của "www" (bất kỳ liên kết tuyệt đối SẼ tiền tố với "www" và tất cả các trang S W được phân phát qua "www")

Điều này phức tạp vì tôi cần truy cập thông qua chức năng được gọi từ 'attachEvent' của IE.

CẬP NHẬT Xin lỗi, tôi đã viết câu hỏi này thực sự. Vấn đề thực sự là làm cho nó hoạt động thông qua một sự kiện, vì IE có một thế giới xử lý sự kiện riêng. Hãy thực hiện theo các bước sau:

function add_event(obj) { 
    if (obj.addEventListener) 
     obj.addEventListener('click', track_file, true); 
    else if (obj.attachEvent) 
     obj.attachEvent("on" + 'click', track_file); 
} 

function track_file(obj) { } 

Dường như "obj" trong track_file không giống nhau trên các trình duyệt - làm cách nào tôi có thể tham chiếu đến những gì được nhấp trong IE?

+0

Đây có phải là tài liệu bạn mở bằng trình duyệt không? –

+0

Xem http://stackoverflow.com/questions/9404793/check-if-same-origin-policy-applies – Seth

Trả lời

5

tôi muốn chỉ ra rằng, nếu bạn đang ở trên so.com, các liên kết sau đây là các URL trong cùng một miền:

(nó có vẻ kỳ quặc, nhưng hai người cuối cùng là hợp lệ: nếu bạn' re on http://so.com, cái cuối cùng sẽ đưa bạn đến http://so.com/mail.google.com/index.php?var=value, cái này hoàn toàn hợp lệ)

Điều này không thực sự trả lời câu hỏi nhưng tôi hy vọng nó sẽ hướng dẫn phần còn lại của câu trả lời. Nếu có bất cứ điều gì khác lạ đủ, cảm thấy tự do để thêm nó.

+1

cũng href = "javascript: ..." là cùng một tên miền, ngoại trừ nếu nó có thay đổi document.location bên trong nó , nhưng tùy thuộc vào bạn, bạn sẽ làm gì với nó. – vsync

3

này nghe có vẻ giống như một câu trả lời hài hước nhưng trong tất cả các mức nó sẽ được khuyến khích rằng bạn cũng có thể làm điều gì đó như:

$('a.external') 

Chắc chắn sự so sánh regex để window.location của bạn là câu trả lời chương trình.

+0

Vì thường là đặt các liên kết bên ngoài với 'target =" _ blank "' để khách truy cập không rời khỏi trang, bạn cũng có thể sử dụng thuộc tính đó nữa. – Gus

2

Phương pháp tập tin đính kèm không phải là cách duy nhất IE và W3 sự kiện thính giả khác nhau. Đối với IE, bạn phải đọc window.event.srcElement; trong W3 nó là event.target nơi event là tham số được truyền cho hàm callback.

Nếu bạn không cần nhiều trình xử lý sự kiện trên liên kết, trình xử lý sự kiện DOM 0 tuổi có thể là cách dễ dàng hơn để bạn tiếp cận điều này, cho phép bạn chỉ ‘chúng tôi’ này nhận đối tượng trên bất kỳ trình duyệt nào.

function bindtolinks() { 
    for (var i= document.links.length; i-->0;) 
     document.links.onclick= clicklink; 
} 

function clicklink() { 
    if (this.host==window.location.host) { 
     dosomething(); 
     return true; // I'm an internal link. Follow me. 
    } else { 
     dosomethingelse(); 
     return false; // I'm an external link. Don't follow, only do something else. 
    } 
} 
+0

Sẽ là tuyệt vời nếu tôi có thể thoát khỏi cách tiếp cận cũ, nhưng đây phải là một kịch bản rất chung chung chỉ áp dụng cho tất cả các liên kết trên trang, một số trong đó có thể có trình xử lý sự kiện đã có. –

+0

Nếu bạn biết bạn đang chạy sau các trình xử lý sự kiện khác, bạn có thể lưu tất nhiên (link.orig_onclick = link.onlick) và gọi lại trình xử lý sự kiện hiện có. – bobince

0

tôi sẽ trả lời các câu hỏi trong bản cập nhật, về các sự kiện trong IE:

function track_file(evt) 
{ 
    if (evt == undefined) 
    { 
    evt = window.event; // For IE 
    } 
    // Use evt 
} 

là cách cổ điển để có được đối tượng sự kiện nhất quán trên các trình duyệt.

Sau đó, tôi sẽ sử dụng các regex để bình thường hóa URL, nhưng tôi không chắc chắn những gì bạn chăm sóc.

[EDIT] Một số mã thực để đưa vào thực hành những gì tôi đã viết ở trên ... :-)

function CheckTarget(evt) 
{ 
    if (evt == undefined) 
    { 
    // For IE 
    evt = window.event; 
//~  event.returnValue = false; 
    var target = evt.srcElement; 
    var console = { log: alert }; 
    } 
    else 
    { 
    target = evt.target; 
//~  preventDefault(); 
    } 
    alert(target.hostname + " vs. " + window.location.hostname); 
    var re = /^https?:\/\/[\w.-]*?([\w-]+\.[a-z]+)\/.*$/; 
    var strippedURL = window.location.href.match(re); 
    if (strippedURL == null) 
    { 
    // Oops! (?) 
    alert("Where are we?"); 
    return false; 
    } 
    alert(window.location.href + " => " + strippedURL); 
    var strippedTarget = target.href.match(re); 
    if (strippedTarget == null) 
    { 
    // Oops! (?) 
    alert("What is it?"); 
    return false; 
    } 
    alert(target + " => " + strippedTarget); 
    if (strippedURL[1] == strippedTarget[1]) 
    { 
//~  window.location.href = target.href; // Go there 
    return true; // Accept the jump 
    } 
    return false; 
} 

Đó của mã kiểm tra, không phải mã sản xuất, rõ ràng!

Các dòng có // ~ nhận xét hiển thị cách thay thế ngăn nhấp chuột vào liên kết để thực hiện bước nhảy. Đó là, bằng cách nào đó, hiệu quả hơn bởi vì nếu tôi sử dụng console.log của Firebug, tò mò trả về false là không hiệu quả.
Tôi đã sử dụng ở đây hành vi "theo liên kết hay không", không biết mục đích cuối cùng thực sự.

Như đã nêu trong các nhận xét, RE có thể đơn giản hơn bằng cách sử dụng tên máy chủ thay vì href ... Tôi để nguyên vì nó đã được mã hóa và có thể hữu ích trong các trường hợp khác.
Một số biện pháp phòng ngừa đặc biệt nên được thực hiện trong cả hai trường hợp để xử lý các trường hợp đặc biệt, như localhost, địa chỉ IP, cổng ...
Tôi đã loại bỏ tên miền, trước khi đọc lại câu hỏi và thấy nó không phải là vấn đề ... Vâng, có lẽ nó có thể hữu ích cho người khác.

Lưu ý: Tôi thấy một giải pháp tương tự trong một câu hỏi để trang trí liên kết: Editing all external links with javascript

+0

Trên thực tế, evt.srcElement.hostname (IE) và this.hostname (những người khác) hoạt động cho tôi –

-2
if(someDomElementWhichIsALink.href.indexOf(window.location) != -1) { 
    // this is targeting your domain 
} 
+0

Điều này sẽ không phát hiện chính xác cùng một tên miền/khác nhau. – Seth

0

Cho một sự kiện nhấp chuột và các yếu tố mục tiêu ban đầu, điều này sẽ làm việc cho câu hỏi ban đầu:

if(target.protocol == window.location.protocol && target.host == window.location.host){ 
} 

Trình duyệt độc đáo chuyển đổi liên kết từ các mẫu khác nhau được đề cập bởi @Tom thành các liên kết đầy đủ, do đó, các giao thức và giá trị máy chủ chỉ cần khớp với tên miền của bạn.

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