JavaScript addEventListener вызывает функцию, но не может обновить глобальную переменную

Потерпите меня, так как я новичок.

Я пишу код на JavaScript и использую .addEventListener на document.getElementById("texts") для отслеживания изменений в раскрывающемся списке HTML. .addEventListener вызывает функцию changeTextValue всякий раз, когда делается выбор. Эта часть работает, насколько я могу console.info изнутри функции, и моя условная логика внутри функции правильно выполняется и отправляется на консоль изнутри функции. Однако весь смысл функции заключается в обновлении переменной (text) вне функции каждый раз, когда происходит событие мыши. Я присвоил функцию переменной и включил в функцию оператор возврата с соответствующей локальной переменной. Все это работает, назначение изначально выполняется за пределами функции и выводится на консоль при первой загрузке страницы. Однако значение переменной никогда не обновляется за пределами функции при возникновении события мыши. В то время как console.info внутри функции обновляются при возникновении события.

Я попробовал просто инициализировать переменную text, не присваивая ей значения. Но затем я получаю сообщение об ошибке: «text.toLowerCase()» не определено.

Я попробовал инициализировать text как пустой массив. А затем вставьте text (вместо chosenText) в функцию с префиксом window, чтобы получить доступ к ней как к глобальной переменной. Это вызвало ошибку: «text.toLowerCase()» не является функцией. Эта ошибка исчезает, когда я возвращаю код в том виде, в котором я его публикую, сохраняя переменную text вне функции, но присваивая ей функцию.

Я чувствую, что мне не хватает чего-то основного. Спасибо за вашу помощь.

'use strict';

const mobyDickText=`Moby Dick text....`;
const huckFinnText=`Huck Finn text....`;
let dropdown = document.getElementById("texts");
let pick=dropdown.value;
const title=pick;
let chosenText;
let text= changeTextValue();
let letterCount;
let lowercaseText;

document.getElementById("book-title").innerHTML = title;

function changeTextValue() {
    pick = dropdown.value;
    if (pick === "huckFinnText") {
         chosenText = huckFinnText;
        console.info(chosenText);
    } else if (pick === "mobyDickText") {
        chosenText = mobyDickText;
        console.info(chosenText);
    } return chosenText;
}

console.info(text);

document.getElementById("texts").addEventListener("change", changeTextValue);

function countFunction(letter) {
    let letterCount=0;
    lowercaseText=text.toLowerCase();
    for (let i=0; i<=text.length-1; i++) {
      if (letter === lowercaseText.charAt(i)) {
          letterCount++;
      }
    } return letterCount;
  } 

const a = countFunction("a");
const b = countFunction("b");
const c = countFunction("c");
const d = countFunction("d");
const e = countFunction("e");
const f = countFunction("f");
const g = countFunction("g");
const h = countFunction("h");
const i = countFunction("i");
const j = countFunction("j");
const k = countFunction("k");
const l = countFunction("l");
const m = countFunction("m");
const n = countFunction("n");
const o = countFunction("o");
const p = countFunction("p");
const q = countFunction("q");
const r = countFunction("r");
const s = countFunction("s");
const t = countFunction("t");
const u = countFunction("u");
const v = countFunction("v");
const w = countFunction("w");
const x = countFunction("x");
const y = countFunction("y");
const z = countFunction("z");

const letters = {
    "A": a,
    "B": b,
    "C": c,
    "D": d,
    "E": e,
    "F": f,
    "G": g,
    "H": h,
    "I": i,
    "J": j,
    "K": k,
    "L": l,
    "M": m,
    "N": n,
    "O": o,
    "P": p,
    "Q": q,
    "R": r,
    "S": s,
    "T": t,
    "U": u,
    "V": v,
    "W": w,
    "X": x,
    "Y": y,
    "Z": z
};

let sortable = [];
for (var num in letters) {
    sortable.push([num, letters[num]]);
}
const sorted=sortable.sort(function(a, b) {
    return b[1] - a[1];
});

let sortedNumbers = [];
for (var value in sorted) {
    sortedNumbers.push(sorted[value][1]);
}

let sortedLetters = [];
for (var value in sorted) {
    sortedLetters.push(sorted[value][0]);
}

for (let item=0; item<sorted.length; item++) {
    let strLetter = item.toString();
    document.getElementById(strLetter).innerHTML = sortedLetters[item];
}

for (let item=0; item<sorted.length; item++) {
    let strNumber = item.toString() + "n";
    document.getElementById(strNumber).innerHTML = sortedNumbers[item].toLocaleString();
} 

let total=0;
for (let item=0; item<sorted.length; item++) {
    total += sortedNumbers[item];
} document.getElementById("total").innerHTML = total.toLocaleString();

let percent = [];
for (var num in sortedNumbers) {
    percent.push((sortedNumbers[num] / total) * 100);
    document.getElementById(num + "p").innerHTML = percent[num].toFixed(1) + "%";
}
<!DOCTYPE html>
<html lang = "en">
  <head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
    <link rel = "stylesheet" href = "styles.css">
  </head>
  <body>
    <main id = "main">
        <form id = "form">
            <select id= "texts" name = "texts" class = "select">
                <option value = "mobyDickText" id = "mobyDick">Moby Dick</option> 
                <option value = "huckFinnText" id = "huckFinn">Huck Finn</option>
            </select>
        </form>
        <table class = "result">
            <tbody>
                <th class = "title" colspan = "3" id = "book-title"></th>
                <tr><td id = "0" class = "letter"></td><td id = "0n" class = "number"></td><td id = "0p" class = "percent"></td></tr>
                <tr><td id = "1" class = "letter"></td><td id = "1n" class = "number"></td><td id = "1p" class = "percent"></td></tr>
                <tr><td id = "2" class = "letter"></td><td id = "2n" class = "number"></td><td id = "2p" class = "percent"></td></tr>
                <tr><td id = "3" class = "letter"></td><td id = "3n" class = "number"></td><td id = "3p" class = "percent"></td></tr>
                <tr><td id = "4" class = "letter"></td><td id = "4n" class = "number"></td><td id = "4p" class = "percent"></td></tr>
                <tr><td id = "5" class = "letter"></td><td id = "5n" class = "number"></td><td id = "5p" class = "percent"></td></tr>
                <tr><td id = "6" class = "letter"></td><td id = "6n" class = "number"></td><td id = "6p" class = "percent"></td></tr>
                <tr><td id = "7" class = "letter"></td><td id = "7n" class = "number"></td><td id = "7p" class = "percent"></td></tr>
                <tr><td id = "8" class = "letter"></td><td id = "8n" class = "number"></td><td id = "8p" class = "percent"></td></tr>
                <tr><td id = "9" class = "letter"></td><td id = "9n" class = "number"></td><td id = "9p" class = "percent"></td></tr>
                <tr><td id = "10" class = "letter"></td><td id = "10n" class = "number"></td><td id = "10p" class = "percent"></td></tr>
                <tr><td id = "11" class = "letter"></td><td id = "11n" class = "number"></td><td id = "11p" class = "percent"></td></tr>
                <tr><td id = "12" class = "letter"></td><td id = "12n" class = "number"></td><td id = "12p" class = "percent"></td></tr>
                <tr><td id = "13" class = "letter"></td><td id = "13n" class = "number"></td><td id = "13p" class = "percent"></td></tr>
                <tr><td id = "14" class = "letter"></td><td id = "14n" class = "number"></td><td id = "14p" class = "percent"></td></tr>
                <tr><td id = "15" class = "letter"></td><td id = "15n" class = "number"></td><td id = "15p" class = "percent"></td></tr>
                <tr><td id = "16" class = "letter"></td><td id = "16n" class = "number"></td><td id = "16p" class = "percent"></td></tr>
                <tr><td id = "17" class = "letter"></td><td id = "17n" class = "number"></td><td id = "17p" class = "percent"></td></tr>
                <tr><td id = "18" class = "letter"></td><td id = "18n" class = "number"></td><td id = "18p" class = "percent"></td></tr>
                <tr><td id = "19" class = "letter"></td><td id = "19n" class = "number"></td><td id = "19p" class = "percent"></td></tr>
                <tr><td id = "20" class = "letter"></td><td id = "20n" class = "number"></td><td id = "20p" class = "percent"></td></tr>
                <tr><td id = "21" class = "letter"></td><td id = "21n" class = "number"></td><td id = "21p" class = "percent"></td></tr>
                <tr><td id = "22" class = "letter"></td><td id = "22n" class = "number"></td><td id = "22p" class = "percent"></td></tr>
                <tr><td id = "23" class = "letter"></td><td id = "23n" class = "number"></td><td id = "23p" class = "percent"></td></tr>
                <tr><td id = "24" class = "letter"></td><td id = "24n" class = "number"></td><td id = "24p" class = "percent"></td></tr>
                <tr><td id = "25" class = "letter"></td><td id = "25n" class = "number"></td><td id = "25p" class = "percent"></td></tr>
                <tr><td class = "footer" colspan = "3" id = "total"></td></tr>
            </tbody>
        </table>
    </main>  
    <script src = "script.js"></script>
  </body>
</html>
```

я посмотрел на это, оно работает, хотя я не уверен, что вы на самом деле пытаетесь сделать

matt 28.02.2024 22:05

Я пытаюсь обновить таблицу HTML, когда пользователь делает выбор в раскрывающемся списке.

ivanheyman 28.02.2024 22:17

какая сумма внизу

matt 28.02.2024 22:20

Несмотря на то, что функция выполняется, как мы видим в console.info, она не выполняет новое присвоение переменной, когда пользователь делает выбор, даже если ее значение возврата изменяется. Как обновить переменную «текст» вне функции всякий раз, когда происходит новое событие addEventListener?

ivanheyman 28.02.2024 22:23

ой, извините, вам придется удалить строку «let selectedText = [];» в функции ChangeTextValue она переопределяет область действия внешней переменной

matt 28.02.2024 22:24

Программа проанализирует строку текста, подсчитает вхождения каждой буквы и отобразит их в таблице. Сумма внизу — общее количество букв в тексте/книге.

ivanheyman 28.02.2024 22:25

заходите и общайтесь в чате Javascript chat.stackoverflow.com/rooms/17/javascript

matt 28.02.2024 22:27

Я попробовал удалить эту строку, но программа выдает тот же результат.

ivanheyman 28.02.2024 22:29

Спасибо за приглашение в чат! Я пока не могу публиковать сообщения, потому что у меня нет 20 очков репутации, потому что я новичок.

ivanheyman 28.02.2024 22:30

Для чего нужны все переменные aCount, bCount и т. д.? Вы никогда ими не пользуетесь.

Barmar 28.02.2024 22:38

О, спасибо, что указали на это. Изначально я планировал сделать это по-другому, но изменил курс. Вы правы, их можно удалить.

ivanheyman 28.02.2024 22:47

Я отредактировал код, удалив переменные aCount, bCount и т. д. Все еще получаю тот же результат. HTML-документ не обновляется при возникновении события мыши.

ivanheyman 28.02.2024 22:53

@mattrichards Еще раз спасибо за помощь мне вчера. И вам также спасибо за положительный/обнадеживающий отзыв. Для новичка это может напугать, но я полон решимости получить профессиональные навыки в JS. Замечательно, что такие люди, как Вы, готовы помочь нам, новичкам :)

ivanheyman 29.02.2024 13:04

@Barmar Еще раз спасибо, что помогли мне вчера, указав на 26 переменных, которые я не использовал. :) ценю, что вы просматриваете мой код!

ivanheyman 29.02.2024 13:19

@ivanheyman, эй, приятель, надеюсь, твои программы идут хорошо, мне никто об этом не говорил, но ты должен голосовать за ответы, которые находишь полезными, не стесняйся, я не имею в виду себя сейчас или что-то в этом роде, просто не забывай в будущем, и ты, надеюсь, это сделаешь приятно плавайте на этом сайте, большая часть людей вам помогает, скоро пообщайтесь снова

matt 02.03.2024 00:25

@mattrichards Привет, Мэтт, спасибо за совет! Я даже не увидел стрелок «за». Я только что проголосовал за ваш ответ, но мне сказали, что для голосования мне нужна репутация 15, но мой отзыв был записан.

ivanheyman 03.03.2024 01:11

@ivanheyman, я действительно не имел в виду себя, я просто был рад, что смог помочь. Если вы попытаетесь увеличить свою репутацию, не задавайте слишком много вопросов, есть вероятность, что в конце вы получите отрицательные голоса, постарайтесь сделать это, желательно отвечая на вопросы, как только вы получите свои 20 представителей, отправляйтесь в этот чат Javascript, удачи, приятель

matt 03.03.2024 07:18

если вы пойдете туда, где приходят вопросы, и ждете, пока кто-то новый задаст вопрос, на который вы, возможно, сможете ответить или найти ответ довольно быстро, тогда ответьте на него, и вы можете довольно легко получить положительный голос

matt 03.03.2024 07:24

И последнее: если вы отвечаете на вопрос, убедитесь, что вы действительно отвечаете на вопрос, иногда легко опубликовать ответ, а позже понять, что вы на самом деле не ответили на то, что вас спрашивали, и получить за это отрицательный голос

matt 03.03.2024 07:28

@mattrichards Спасибо за все советы, Мэтт. Я очень ценю это! Мне не терпится попасть в этот чат :)

ivanheyman 03.03.2024 12:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
20
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ок, вот :)

ты был не слишком далеко

'use strict';

let aCount = 0,
  bCount = 0,
  cCount = 0,
  dCount = 0,
  eCount = 0,
  fCount = 0,
  gCount = 0,
  hCount = 0,
  iCount = 0,
  jCount = 0,
  kCount = 0,
  lCount = 0,
  mCount = 0,
  nCount = 0,
  oCount = 0,
  pCount = 0,
  qCount = 0,
  rCount = 0,
  sCount = 0,
  tCount = 0,
  uCount = 0,
  vCount = 0,
  wCount = 0,
  xCount = 0,
  yCount = 0,
  zCount = 0;

const mobyDickText=`Moby Dick text....`;
const huckFinnText=`Huck Finn text....`;
let dropdown = document.getElementById("texts");
let pick=dropdown.value;
const title=pick;
let chosenText;


//edit

let text



let letterCount;
let lowercaseText;

document.getElementById("book-title").innerHTML = title;

function changeTextValue() {
  
    pick = dropdown.value;
    if (pick === "huckFinnText") {
         chosenText = huckFinnText;
        console.info(chosenText);
    } else if (pick === "mobyDickText") {
        chosenText = mobyDickText;
        console.info(chosenText);
    } 


//edit

    text=chosenText;
    update();
    //return chosenText;




}








//edit

//console.info(text);
changeTextValue();





document.getElementById("texts").addEventListener("change", changeTextValue);

function countFunction(letter) {
    let letterCount=0;
    lowercaseText=text.toLowerCase();
    for (let i=0; i<=text.length-1; i++) {
      if (letter === lowercaseText.charAt(i)) {
          letterCount++;
      }
    } return letterCount;
  } 





//edit

function update(){
  
  
const a = countFunction("a");
const b = countFunction("b");
const c = countFunction("c");
const d = countFunction("d");
const e = countFunction("e");
const f = countFunction("f");
const g = countFunction("g");
const h = countFunction("h");
const i = countFunction("i");
const j = countFunction("j");
const k = countFunction("k");
const l = countFunction("l");
const m = countFunction("m");
const n = countFunction("n");
const o = countFunction("o");
const p = countFunction("p");
const q = countFunction("q");
const r = countFunction("r");
const s = countFunction("s");
const t = countFunction("t");
const u = countFunction("u");
const v = countFunction("v");
const w = countFunction("w");
const x = countFunction("x");
const y = countFunction("y");
const z = countFunction("z");

const letters = {
    "A": a,
    "B": b,
    "C": c,
    "D": d,
    "E": e,
    "F": f,
    "G": g,
    "H": h,
    "I": i,
    "J": j,
    "K": k,
    "L": l,
    "M": m,
    "N": n,
    "O": o,
    "P": p,
    "Q": q,
    "R": r,
    "S": s,
    "T": t,
    "U": u,
    "V": v,
    "W": w,
    "X": x,
    "Y": y,
    "Z": z
};

let sortable = [];
for (var num in letters) {      //console.info(num,letters[num]);
    sortable.push([num, letters[num]]);
}
const sorted=sortable.sort(function(a, b) {
    return b[1] - a[1];
});

let sortedNumbers = [];
for (var value in sorted) {
    sortedNumbers.push(sorted[value][1]);
}

let sortedLetters = [];
for (var value in sorted) {
    sortedLetters.push(sorted[value][0]);
}

for (let item=0; item<sorted.length; item++) {
    let strLetter = item.toString();
    document.getElementById(strLetter).innerHTML = sortedLetters[item];
}

for (let item=0; item<sorted.length; item++) {
    let strNumber = item.toString() + "n";
    document.getElementById(strNumber).innerHTML = sortedNumbers[item].toLocaleString();
} 

let total=0;
for (let item=0; item<sorted.length; item++) {
    total += sortedNumbers[item];
} document.getElementById("total").innerHTML = total.toLocaleString();

let percent = [];
for (var num in sortedNumbers) {
    percent.push((sortedNumbers[num] / total) * 100);
    document.getElementById(num + "p").innerHTML = percent[num].toFixed(1) + "%";
}



//edit

}//update
<!DOCTYPE html>
<html lang = "en">
  <head>
    <meta charset = "UTF-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1.0">
    <link rel = "stylesheet" href = "styles.css">
  </head>
  <body>
    <main id = "main">
        <form id = "form">
            <select id= "texts" name = "texts" class = "select">
                <option value = "mobyDickText" id = "mobyDick">Moby Dick</option> 
                <option value = "huckFinnText" id = "huckFinn">Huck Finn</option>
            </select>
        </form>
        <table class = "result">
            <tbody>
                <th class = "title" colspan = "3" id = "book-title"></th>
                <tr>
                      <td id = "0" class = "letter"></td>
                      <td id = "0n" class = "number"></td>
                      <td id = "0p" class = "percent"></td>
                </tr>
                <tr><td id = "1" class = "letter"></td><td id = "1n" class = "number"></td><td id = "1p" class = "percent"></td></tr>
                <tr><td id = "2" class = "letter"></td><td id = "2n" class = "number"></td><td id = "2p" class = "percent"></td></tr>
                <tr><td id = "3" class = "letter"></td><td id = "3n" class = "number"></td><td id = "3p" class = "percent"></td></tr>
                <tr><td id = "4" class = "letter"></td><td id = "4n" class = "number"></td><td id = "4p" class = "percent"></td></tr>
                <tr><td id = "5" class = "letter"></td><td id = "5n" class = "number"></td><td id = "5p" class = "percent"></td></tr>
                <tr><td id = "6" class = "letter"></td><td id = "6n" class = "number"></td><td id = "6p" class = "percent"></td></tr>
                <tr><td id = "7" class = "letter"></td><td id = "7n" class = "number"></td><td id = "7p" class = "percent"></td></tr>
                <tr><td id = "8" class = "letter"></td><td id = "8n" class = "number"></td><td id = "8p" class = "percent"></td></tr>
                <tr><td id = "9" class = "letter"></td><td id = "9n" class = "number"></td><td id = "9p" class = "percent"></td></tr>
                <tr><td id = "10" class = "letter"></td><td id = "10n" class = "number"></td><td id = "10p" class = "percent"></td></tr>
                <tr><td id = "11" class = "letter"></td><td id = "11n" class = "number"></td><td id = "11p" class = "percent"></td></tr>
                <tr><td id = "12" class = "letter"></td><td id = "12n" class = "number"></td><td id = "12p" class = "percent"></td></tr>
                <tr><td id = "13" class = "letter"></td><td id = "13n" class = "number"></td><td id = "13p" class = "percent"></td></tr>
                <tr><td id = "14" class = "letter"></td><td id = "14n" class = "number"></td><td id = "14p" class = "percent"></td></tr>
                <tr><td id = "15" class = "letter"></td><td id = "15n" class = "number"></td><td id = "15p" class = "percent"></td></tr>
                <tr><td id = "16" class = "letter"></td><td id = "16n" class = "number"></td><td id = "16p" class = "percent"></td></tr>
                <tr><td id = "17" class = "letter"></td><td id = "17n" class = "number"></td><td id = "17p" class = "percent"></td></tr>
                <tr><td id = "18" class = "letter"></td><td id = "18n" class = "number"></td><td id = "18p" class = "percent"></td></tr>
                <tr><td id = "19" class = "letter"></td><td id = "19n" class = "number"></td><td id = "19p" class = "percent"></td></tr>
                <tr><td id = "20" class = "letter"></td><td id = "20n" class = "number"></td><td id = "20p" class = "percent"></td></tr>
                <tr><td id = "21" class = "letter"></td><td id = "21n" class = "number"></td><td id = "21p" class = "percent"></td></tr>
                <tr><td id = "22" class = "letter"></td><td id = "22n" class = "number"></td><td id = "22p" class = "percent"></td></tr>
                <tr><td id = "23" class = "letter"></td><td id = "23n" class = "number"></td><td id = "23p" class = "percent"></td></tr>
                <tr><td id = "24" class = "letter"></td><td id = "24n" class = "number"></td><td id = "24p" class = "percent"></td></tr>
                <tr><td id = "25" class = "letter"></td><td id = "25n" class = "number"></td><td id = "25p" class = "percent"></td></tr>
                <tr><td class = "footer" colspan = "3" id = "total"></td></tr>
            </tbody>
        </table>
    </main>  
    <script src = "script.js"></script>
  </body>
</html>
  • я поместил код, который обновлял таблицу, в функцию под названием update

  • кажется, что общая обработка выполнялась над глобальной переменной с именем text, я не звонил changeTextValue, чтобы сразу его инициализировать

  • в changeValueText вместо того, чтобы возвращать значение, я присвоил его к глобальной переменной text, а затем вызвал эту update функцию

  • я подождал, пока вы не подтвердите, что глобальная переменная установлена ​​с помощью console.info затем вручную вызвал ваш changeValueText, чтобы update функция была вызвана, и ваша таблица показала некоторые результаты

да, возможно, ты новичок, но мы все с этого начинали, твоя программа показала изобретательность, и ты старался подтолкнуть себя, молодец :)

Омг, спасибо. В этом есть смысл поместить обновления HTML внутри функции и вызвать эту функцию внутри функции ChangeTextValue. Это гарантирует, что HTML будет обновляться каждый раз, когда происходит событие мыши. Гений. Спасибо!

ivanheyman 28.02.2024 23:36

Другие вопросы по теме