8

为了通过谷歌分析跟踪非 HTML 文档,我需要提到的算法。它应该:

  • 不对域进行硬编码
  • 忽略协议(即http/https)
  • 不用担心“www”的存在/不存在(任何绝对链接都将以“www”为前缀,所有页面都将通过“www”提供)

这很复杂,因为我需要通过仅 IE 的“attachEvent”调用的函数来访问它。

更新对不起,我对这个问题的措辞非常糟糕。真正的问题是通过事件让它工作,因为 IE 有自己的事件处理世界。采取以下措施:

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) { }

似乎 track_file 中的“obj”在浏览器中是不一样的——我如何才能引用在 IE 中单击的内容?

4

6 回答 6

5

我想指出,如果您在 so.com 上,以下链接是同一域中的 URL:

(这可能看起来很奇怪,但最后两个是有效的:如果您在http://so.com上,最后一个会将您带到http://so.com/mail.google.com/index。 php?var=value,这是完全有效的)

这并不能真正回答问题,但我希望它能指导其余的答案。如果还有什么奇怪的地方,欢迎补充。

于 2008-11-25T11:59:41.443 回答
3

这听起来像是一个喜剧答案,但说真的,建议您也可以执行以下操作:

$('a.external')

当然,正则表达式与您的 window.location 的比较是程序化的答案。

于 2008-11-25T12:21:28.417 回答
3

附加方法并不是 IE 和 W3 事件侦听器不同的唯一方式。对于 IE,您必须阅读 window.event.srcElement;在 W3 中它是 event.target,其中 event 是传递给回调函数的参数。

如果您不需要链接上的多个事件处理程序,老式的 DOM 0 事件处理程序可能是您处理此问题的更简单方法,允许您只使用“this”即可在任何浏览器上获取对象。

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.
    }
}
于 2008-11-25T12:35:47.813 回答
1

我将在更新中回答有关 IE 事件的问题:

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

是跨浏览器获取一致事件对象的经典方法。

在那之后,我会使用正则表达式来规范化 URL,但我不确定你在看什么。

[编辑] 一些真正的代码可以将我上面写的内容付诸实践...... :-)

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;
}

那是测试代码,而不是生产代码,很明显!

带有 //~ 注释的行显示了阻止单击链接进行跳转的替代方法。不知何故,它更有效,因为如果我使用 Firebug 的 console.log,奇怪的是 return false 是无效的。
我在这里使用了“是否关注链接”的行为,不知道真正的最终目的。

正如评论中所指出的,RE 可以通过使用主机名而不是 href 更简单......我保留它是因为它已经编码并且可能在其他情况下有用。
在这两种情况下都应该采取一些特殊的预防措施来处理特殊情况,比如本地主机、IP 地址、端口......
我去掉了域名,然后重新阅读问题并看到它没有问题......好吧,也许它对其他人有用。

注意:我在装饰链接的问题中展示了类似的解决方案:Editing all external links with javascript

于 2008-11-25T12:36:54.877 回答
0

给定一个点击事件和原始目标元素,这应该适用于原始问题:

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

浏览器很好地将链接从@Tom 提到的各种模式转换为完整链接,因此协议和主机值只需要与您的域匹配。

于 2010-10-19T15:17:31.283 回答
-2
if( someDomElementWhichIsALink.href.indexOf(window.location) != -1 ) {
  // this is targeting your domain
}
于 2008-11-25T12:39:41.300 回答