css 纯javaScript函数在调用时未定义

2ledvvac  于 2023-03-24  发布在  Java
关注(0)|答案(2)|浏览(117)

我一直试图找到这个bug,但是我找不到。在我的代码中,除了函数“typewriter”拒绝被!undefined之外,所有的东西都运行得很好。

var xtrans = document.getElementById("xtext");
var xshowed = document.getElementById("xcontain");

function xsend() {
  var gotten = xtrans.value;
  if (/^\s*$/.test(gotten) == true) { // the crazy  /^\s*$/.test(gotten) there is to check for a whitespace only on a condition that no text has been added. its a returns a boolean value, "true or false,"" so i set it to true, and if it happens, the code of block is executed.
    return false; //all actions if the condition is true will be aborted
  }
  else {
    xshow(gotten);
    xtrans.value = ""; //this is to clear the text after clicking send
  }
}

function xshow(gotten) { //gooten was put here so it could pass its value below since its value was originally gotten in another function which will not work elsewhere like a global stuff.
  const ximagine = document.createElement("div"); //to create an element so the text from gotten can be placed in it as its content.
  ximagine.textContent = gotten; //to get the text that gotten carries and place it into the element created.

  if (ximagine.textContent) { //this is to make sure a text which is null or u defined will not go past this block of code. ( like a  filter).
    var xfinal = xshowed.appendChild(ximagine); //the container xshowed where the x imagine was appended to had a blue border so i could see where the text entered. all the text entered the border but i wanted them to look somewhat seperate, hence i cleared all design from the container to make it look blank and i made designs to the incoming texts so they would look like they were sent differently.
    xfinal.classList.add("ended"); //this is to add whatever design i want.
    xbot(gotten) //call this function if everything is successful
  }
  else {
    document.write("fatal error, please refresh this page and don't put such text anymore, else you will be suspended for 6 months");
  }
}

function xbot(gotten) {
  //  gotten.trim(); //to remove whitespace both from front and back of the string.
  if (gotten == "Hi" || gotten == "Hello" || gotten == "Robot?" || gotten == "Anyone?") {
    console.log("validated");
    const xpro = document.createElement("div");
    var xreturn = xshowed.appendChild(xpro);
    xreturn.classList.add("xended");
    xblinker = document.createElement("p");
    xblinker.id = "blink";
    var xreply = document.createElement("p");
    xreply.id = "typed";
    xpro.appendChild(xblinker);
    xpro.after(xreply); //to add the  xreply element and xblinker element to the parent element xpro when they're formed
    var xreplyy = document.getElementById("typed");
    var blinky = document.getElementById("blink"); //this is to get the element that will be blinking in front of text.

    blinky.style.display = "inline";
    blinky.style.borderRight = "10px solid white";

    // set up text to print, each item in array is new line
    var aText = new Array(
      "There are only 2 types of people in the world:",
      "The ones who have dominated in increasing their capacity to think, and the ones who wallow in ignorance"); //the two text strings, but here they're like objects because of the "new" keyword.
    var iSpeed = 100; // time delay in typing out each character 
    var iIndex = 0; // start typing the array text at this position, thats at beginning.
    var iArrLength = aText[0].length; // the length of the first string, thats the one before the comma of the text array.
    var iScrollAt = 20; // point at which text start scrolling up, start scrolling up at this many lines. its not really important.
    var iTextPos = 0; // the text position after displaying a character.
    var sContents = ""; // initialise contents variable
    var iRow; // Not so important, This variable is used to keep track of which lines of text have already been typed out and should be displayed on the web page.

    typewriter(); //calls the function to trigger the code below 

    function typewriter() {
      sContents = ""; //repeated though
      iRow = Math.max(0, iIndex - iScrollAt); //rhis only tries to see which is the largest number. if you solve iindex-iscrollat, you'd get -20. between -20 and zero, zero is bigger, so math.max picks it and it is now assigned to iRow. you can console.log iRow to check its value. i think it is better to just say iRow is equal to zero, instead of passing through the stress.
      var destination = document.getElementById("typed"); //get the element that it the array text would be appended to.

      while (iRow < iIndex) { //the while here is a type of loop, while the iRow is less than the position of the text in the array. execute the below code as long as the condition is true. this condition is only true when the iIndex has been moved to 1 or the next string. that means this code for the next text string after the first. tested with console.log(iRow, iIndex);
        sContents += aText[iRow] + "<br>"; //mind you, increment of zero is 1.
        iRow++;
      }

      destination.innerHTML = sContents + aText[iIndex].substring(0, iTextPos) + blinky.innerHTML; //this code will run first for the first string text ie iIndex equal to 0. then it will run a second time, but this time it will add the next steing text to the first one, which will make them stay in the same element called destination it was tested with this "console.log(sContents);" 

      //the substring starts from 0, thats first character and returns the following characters as iTextPos increments. one by one.
      if (iTextPos++ == iArrLength) { //the heart of the code. this says if the increment in the textposition is equal to the length of the text in that particular string. it won't work if iTextpos++ is put as iTextpos, because it is always incrementing. check this out to see "console.log(iTextPos);"
        iTextPos = 0; //text position is reseted here.blinky.style.borderRight = "10px solid white"; //to show itself
        blinky.style.display = "inline"; //very important, to make it inline with the text which i alredy made display as inline too, in order for them to appear on same line together.
        iIndex++; //iIndex is incremented, and thats what causes iIndex to turn to 1 meaning next line, if theres another, it will turn to 2 and so on.
        if (iIndex != aText.length) { //it will almost likely never be equal to it, so the below code will always run.
          iArrLength = aText[iIndex].length; //the iArrLength is updated with new length for new string or next string.
          setTimeout("typewriter()", 500); //function is then called again after 500ms, so as to render the next text out.
        }
      }
      else {
        setTimeout("typewriter()", iSpeed); //if no new line, call function after iSpeed value
      }
    }
  }
}

我试图使一种机器人,以回应已经固定的文本输入与文本,我填补了它。
我正在尝试复制我自己的chatgpt前端。所以它对文本有一些类似chatgpt的效果。
这就是全部的源代码。代码有点复杂。
闪光灯的 Flink 效果将由css来处理,我选择这个是因为如果我单独使用css来做文本效果,我最多只能做一行文本,因为它使用100%的文本宽度来显示它,不像js。

问题typewriter()没有调用函数typewriter()。它只是在控制台中未定义。我不认为我在代码中有任何错别字(尽管不是注解)。

我要做的是调用这个函数,因为没有它,要输入的文本就不能被输入,所以我有一个光标在它附加的容器中 Flink 。
抱歉代码有点乱,我快疯了。
我尝试使用"use strict",因为我从堆栈溢出的某个地方读到,在if语句下运行的函数运行得不好,我尝试使用setInterval运行代码,认为可能typewriter()调用的位置不好。然后我通过将clearInterval首先放入要调用的函数中来清除它。我希望它能正常工作。

dly7yett

dly7yett1#

与其将函数作为字符串传递给setTimeout(就像你对setTimeout("typewriter()", 500);所做的那样),你需要像这样传递函数本身:setTimeout(typewriter, 500);。其他setTimeout也是如此:setTimeout(typewriter, iSpeed); .
为什么不能在这里使用字符串?因为,正如注解中提到的,使用字符串而不是传递函数将在global scope中运行字符串,并且由于typewriter是在另一个函数中定义的,因此它将无法从全局范围访问。

rkue9o1l

rkue9o1l2#

我不是很精通闭包,但我认为你的代码失败是因为setTimeout在最初调用它时(在超时发生之前)创建了一个闭包。这使得你的函数还不存在(我认为)。你可以通过使用setTimeout的其他语法来解决这个问题,在这里你给予它一个回调函数而不调用它。所以不要使用

setTimeout("typewriter()", 500);

尝试

setTimeout(typewriter, 500);

下面我将两个函数放在一起,一个使用您当前的语法,另一个使用我建议的语法

myFunc(10)

// works
function myFunc(num) {
  if (num > 0) {
    console.log(num)
    setTimeout(() => myFunc(num - 1), 500)
  }
}

myOtherFunc(10)

// doesn't work
function myOtherFunc(num) {
  if (num > 0) {
    console.log(num)
    setTimeout('myOtherFunc(num - 1)', 500)
  }
}

相关问题