0

我对 Web 开发和 javascript 还是很陌生。为了使我的网站更易于维护,我决定使用 Javascript 从文本文件中读取“导航栏”并将其添加到每个页面的顶部。我现在要做的是创建一个允许我指定链接和“链接深度”的函数,以返回指向我的页面的相对链接。这是功能:

 function increaseLinkDepth(aLink, aDepth) {
     var result = aLink;
     for(i = 0;i < aDepth;i++) {
         result = "../" + result;
     }
     return result;
 } 

现在,我有一点在桌面和移动设备上开发的经验,所以这是一个非常简单的功能。如果我这样调用函数:/increaseLinkDepth("index.html", 1),我希望得到以下结果:../index.html。当我在网站上运行 javascript 时,我确实明白了这一点。现在,当我在以下代码中调用该函数时:

 var anchors = document.getElementsByTagName("a");
    for(i = 0;i < anchors.length;i++) {
        var lAnchor = anchors[i];
        var lAnchorLink = lAnchor.getAttribute("href");
        if(lAnchorLink.substring(0, 4) != "http") {
            var newLink = increaseLinkDepth(lAnchorLink, 1);
            //alert(newLink);
            lAnchor.setAttribute("href", newLink);
        }
    }

我最终陷入某种无休止的循环,导致我不得不重新启动浏览器。它应该寻找的链接是:

  • 索引.html
  • 事件.html
  • about.html

它找到了所有三个,但循环发生在 about.html 链接上。我不确定我的代码中是否遗漏了某些内容(可能看得太久了)。但我没有看到我在哪里遇到这个问题。

现在,我确实明白这可能不是实现此目的的最佳方法,如果不是,请告诉我,这是我认为创建导航栏的唯一方法,我不必更改 HTML每一页。

4

3 回答 3

3

您从未i在任一范围内声明,因此两个循环都在重置全局i变量。

为避免全局污染,请务必将所有代码包装在IIFE中,并添加"use strict"指令:

(function () {
    "use strict";
    ...your code here...
}());

然后浏览器控制台会告诉您您在这些范围内使用了未声明的变量。

您提供的代码的净化版本将是:

(function () {
    "use strict";

    //variables declared at the top of the scope that they belong to
    var anchors,
        i,
        lAnchor,
        lAnchorLink,
        newLink;

    //function declarations follow variable declarations
    function increaseLinkDepth(aLink, aDepth) {
        var result,
            i;
        result = aLink;
        for (i = 0; i < aDepth; i++) {
            result = "../" + result;
        }
        return result;
    }

    //assignment and execution occurs after declarations
    anchors = document.getElementsByTagName('a');
    for (i = 0; i < anchors.length; i++) {
        lAnchor = anchors[i];
        lAnchorLink = lAnchor.getAttribute('href');
        if (lAnchorLink.substring(0, 4) !== 'http') {
            newLink = increaseLinkDepth(lAnchorLink, 1);
            //alert(newLink);
            lAnchor.setAttribute("href", newLink);
        }
    }

    ...more code...
}());
于 2013-09-03T14:34:29.673 回答
0

您正在使用分配给 'i' 而没有使用 var 将其声明为局部变量 - 在 JavaScript 中,这会创建一个全局变量,这意味着您的两个函数都使用相同的索引器。

在每个函数的顶部添加一个var i;,你应该没问题。

于 2013-09-03T14:35:22.003 回答
0

如果在声明变量时忘记使用 var 关键字,它将默认为全局范围。在您的情况下,问题在于 i 变量,它在两种方法中都引用了全局范围内的同一个变量。简而言之,伪代码是:

for (i=0; i<n; i++) {
  for (i=0; i<m; i++) {
    doStuff();
  }
}

将您的代码更改为以下内容:

function increaseLinkDepth(aLink, aDepth) {
     var result = aLink;
     for(var i = 0;i < aDepth;i++) {
         result = "../" + result;
     }
     return result;
 } 

在此处阅读更多信息:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var

于 2013-09-03T14:36:03.383 回答