Как мне добавить функции в оператор переключения JavaScript?

#javascript

#javascript

Вопрос:

Я разрабатываю преобразователь температуры и пытаюсь изменить функцию преобразования в зависимости от выбранного устройства. Фаренгейт — это вычисление по умолчанию, и я не могу изменить его на другие преобразования при переключении единицы измерения. Как я могу добавить свои функции преобразования в оператор переключения?

 // Select unit
const units = document.querySelector('#units');

units.addEventListener('change', function(e) {  
  let selectedUnit = units.selectedIndex;
  let degree = document.querySelector('#degree');  
        
  switch(selectedUnit) {
    case 0:
    degree.innerHTML = "amp;deg;F";
    document.getElementById('tag1').innerHTML = "amp;deg;C";
    document.getElementById('tag2').innerHTML = "amp;deg;R";
    document.getElementById('tag3').innerHTML = "amp;deg;K";
    document.getElementById('fahrenheit').placeholder = "Degrees fahrenheit";
    
    break;

    case 1:
    degree.innerHTML = "amp;deg;C";    
    document.getElementById('tag1').innerHTML = "K";
    document.getElementById('tag2').innerHTML = "amp;deg;R";
    document.getElementById('tag3').innerHTML = "amp;deg;F";
    document.getElementById('fahrenheit').placeholder = "Degrees Celsius";
    break;

    case 2:
    degree.innerHTML = "amp;deg;R";    
    document.getElementById('tag1').innerHTML = "amp;deg;C";
    document.getElementById('tag2').innerHTML = "K";
    document.getElementById('tag3').innerHTML = "amp;deg;F";
    document.getElementById('fahrenheit').placeholder = "Degrees Rankine";
    break;

    case 3:    
    degree.innerHTML = "K";        
    document.getElementById('tag1').innerHTML = "amp;deg;C";
    document.getElementById('tag2').innerHTML = "amp;deg;R";
    document.getElementById('tag3').innerHTML = "amp;deg;F";
    document.getElementById('fahrenheit').placeholder = "Kelvin";
    break;

    default:
    degree.innerHTML = "amp;deg;F";
    document.getElementById('fahrenheit').placeholder = "Degrees Fahrenheit";
    break;
  }
});

// Listen for submit
document.querySelector('#temp-form').addEventListener('submit', function(e) {
  // Hide results
  document.querySelector('#results').style.display = 'none';

  // Show loader
  document.querySelector('#loading').style.display = 'block';

  setTimeout(calculateResults, 2000);
  
  e.preventDefault();
});

// Calculate Results
function calculateResults(e){
  console.log('Calculating...');
  // UI Vars
  const fahrenheitInput = document.querySelector('#fahrenheit');
  const celsiusInput = document.querySelector('#celsius');
  const rankineInput = document.querySelector('#rankine');
  const kelvinInput = document.querySelector('#kelvin');

  function fahrenheitConversion() {
    const ftemp = parseFloat(fahrenheitInput.value);
    const ctemp = (ftemp - 32) * (5/9);
    const rtemp = ftemp   459.67;
    const ktemp = (ftemp - 32) * (5/9)   273.15;
    
    celsiusInput.value = ctemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function celsiusConversion() {
    const ctemp = parseFloat(celsiusInput.value);
    const ftemp = (ctemp * (9/5))   32;
    const rtemp = (ctemp * (9/5))   491.67;
    const ktemp = ctemp   273.15;
    
    fahrenheitInput.value = ftemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function rankineConversion() {
    const rtemp = parseFloat(rankineInput.value);
    const ctemp = (rtemp - 491.67) * (5/9);
    const ftemp = rtemp - 459.67;
    const ktemp = rtemp * (5/9);
    
    celsiusInput.value = ctemp.toFixed(2);
    fahrenheitInput.value = ftemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function kelvinConversion() {
    const ktemp = parseFloat(kelvinInput.value);
    const ctemp = ktemp - 273.15;
    const rtemp = ktemp * (9/5);
    const ftemp = (ktemp - 273.15) * (9/5)   32;
    
    celsiusInput.value = ctemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    fahrenheitInput.value = ftemp.toFixed(2);
  }
  
  // Show results
  document.querySelector('#results').style.display = 'block';

  // Hide loader
  document.querySelector('#loading').style.display = 'none';

  fahrenheitInput.addEventListener('submit', fahrenheitConversion());
  celsiusInput.addEventListener('submit', celsiusConversion());
  rankineInput.addEventListener('submit', rankineConversion());
  kelvinInput.addEventListener('submit', kelvinConversion());
} 

Комментарии:

1. .value Свойства элементов HTML всегда являются строками . Вы должны изменить свои case выражения, чтобы они были строками, а не числами, или преобразовать входное значение в число.

2. добавьте свой HTML (#units — это переключатель или выбор ?)

3. Есть гораздо лучший способ сделать это. Вместо того, чтобы использовать идентификаторы tag1, tag2, просто добавьте все четыре типа градусов (id = ‘celsius’, id = ‘fahrenheit’) для полей преобразования, затем скройте (установите css display = «none») тот, который соответствует входной температуре.

4. Кроме того, это идеальный случай для использования матрицы и преобразования температур с использованием линейной алгебры

Ответ №1:

Я думаю, что ваша переменная представляет собой строку, но ваш оператор переключения case работает с числами. Если вы будете бороться с кодом и почему делаете то, что делаете, вы можете сделать несколько вещей.

  • Поместите много консоли.просмотрите код, чтобы показать вам, что происходит. Также выведите тип переменных https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof таким образом, вы будете знать, что вы получаете. Не очень хорошо оставлять материал для отладки / ведения журнала в производственном коде, но при возникновении проблем вы можете оставить регистраторы под защитой глобальной переменной

если (debug_unit_conversion) console.log(……

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

Сам код это можно было бы сделать многими другими способами, в целом вы не хотите, чтобы операторы переключения регистров превращались в огромные, шаблон проектирования команд хорош для исправления этого: https://www.dofactory.com/javascript/design-patterns/command или вы можете сделать что-то среднее и иметь только обратные вызовы для определенных параметров для вызова кода.

Это может быть придирка, потому что ее уже можно рассматривать как часть view, а view может иметь немного логики. Но мне кажется, что бизнес-логика (контроллер) частично перекрывается с вашей презентацией (представлением), вы могли бы разделить функцию на две, первая будет просто решать, какие вещи отображать в каком порядке, а вторая — отображать их. Таким образом, первый вернет массив содержимого innerHTML, а второй применит этот массив к самому HTML. Затем для каждого «модуля» вторая функция может быть использована повторно, и в какой-то степени вы сможете изменить способ представления данных (или, если вы найдете лучший способ обновить HTML) без необходимости изменять логическую часть того, что будет отображаться в каком порядке.

Например

document.getElementById(‘fahrenheit’).placeholder = «Градусы Цельсия»;

может показаться запутанным, представьте, что вы возвращаетесь к этому коду через несколько лет, лучший код — это тот, который самодокументируется, и это может вас смутить. Будет ли ‘unit’, ‘unitDescription’ или ‘unitText’ более подходящими?