Vanilla JavaScript基于<option>值更改api端点

时间:2019-07-18 21:27:11

标签: javascript html css

我正在使用以下语言创建货币转换器应用:“ https://exchangeratesapi.io/” API,并且我尝试更改端点“ base =”,具体取决于使用API​​中的数据动态创建并添加到currencyArr []并循环遍历以创建每个选项。我想控制网址更改的标签的ID为“ top-select”

例如,如果选择了GBP,则网址应类似于“ https://api.exchangeratesapi.io/latest?base=GBP”。

我已经看到类似的问题,这些问题都基于React,JQuery或AJAX,但是我使用的是普通JavaScript,还不知道如何使用这些库。

let currencyArr = [];
let ratesArr = [];
window.addEventListener("load", () => {
	let api = "https://api.exchangeratesapi.io/latest?base=";
	fetch(api)
		.then(response => {
			return response.json();
		})
		.then(data => {
			for (currency in data.rates) {
				currencyArr.push(currency);
				ratesArr.push(data.rates[currency]);

				// create 'option' element here
				const optionTop = document.createElement("option");
				const optionBottom = document.createElement("option");
				optionTop.textContent = currency;
				optionBottom.textContent = currency;
				document.querySelector("#top-select").appendChild(optionTop);
				document.querySelector("#bottom-select").appendChild(optionBottom);
			}

			document.querySelector("#input").addEventListener("keyup", convert);
			document
				.querySelector("#bottom-select")
				.addEventListener("change", convert);
			function convert() {
				const input = document.querySelector("#input");
				let bottomSelectValue = document.querySelector("#bottom-select").value;

				for (let i = 0; i < currencyArr.length; i++) {
					if (bottomSelectValue === currencyArr[i]) {
						document.querySelector("#converted").value = parseFloat(
							ratesArr[i] * input.value
						).toFixed(2);
					}
					if (isNaN(document.querySelector("#converted").value)) {
						document.querySelector("#converted").value =
							"Please Enter A Number";
					}
				}
			}
		});
});
html {
	font-family: "Lato", sans-serif;
	font-weight: thin;
	background-image: linear-gradient(to right top, #90d0ff, #008ef7);
	color: white;
	height: 100vh;
	overflow: hidden;
}
h1 {
	text-align: center;
	font-size: 5em;
}
.container {
	width: 100%;
	height: 80%;
	display: flex;
	align-items: center;
	flex-direction: column;
	text-align: center;

	justify-content: center;
	align-items: center;
}

.container input {
	background: transparent;
	border: none;
	border-bottom: 0.5vh solid white;
	font-size: 7em;
	max-width: 100%;
	outline: none;
	font-family: "Lato", sans-serif;
	font-weight: thin;
	color: white;
	text-align: center;
	overflow: visible;
}
::placeholder {
	/* Chrome, Firefox, Opera, Safari 10.1+ */
	color: white;
	opacity: 1;
	/* Firefox */
}

:-ms-input-placeholder {
	/* Internet Explorer 10-11 */
	color: white;
}

::-ms-input-placeholder {
	/* Microsoft Edge */
	color: white;
}

.container select {
	background: transparent;
	color: white;
	padding: 20px;
	width: 80px;
	height: 60px;
	border: none;
	font-size: 20px;
	box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
	-webkit-appearance: button;
	outline: none;
	margin-top: 5%;
}
.converted {
	pointer-events: none;
	margin-top: 5%;
}
 
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<title>Currency Converter</title>
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<link rel="stylesheet" href="main.css" />
		<link
			href="https://fonts.googleapis.com/css?family=Lato:300&display=swap"
			rel="stylesheet"
		/>
	</head>

	<body>

	
			<h1>Currency Converter</h1>
			
			<div class="container" id="ctn1">
				<input type="text"  id="input" autocomplete="off" placeholder="Enter your number" onfocus="this.placeholder = ''" onblur="this.placeholder ='Enter your number'"/>

				<select id="top-select"> </select>
		

			<div class="container" id="ctn2">
				<input type="text" class="converted" id="converted" autocomplete="off" placeholder="0.00" />
				<select id="bottom-select"> </select>
			</div>
		
		<script src="main.js"></script>
	</body>
</html>

Codepen链接只是为了防止API在堆栈溢出代码段中无法正常使用:https://codepen.io/oliknight/pen/rXaBBZ

2 个答案:

答案 0 :(得分:1)

您只需要使用要提取的硬币设置变量,并为选择器设置一个侦听器功能onchange,因此,每次更改选择器时,提取功能都会再次运行,但基值你想要的。

这是有效的代码段(我将其缩小以便可以容纳页面):

const baseUrl = 'https://api.exchangeratesapi.io/latest?base='
const topSelector = document.getElementById('top-select')
const bottomSelector = document.getElementById('bottom-select')
const converted = document.querySelector('#converted')
const input = document.querySelector('#input')

window.addEventListener('load', () => {
  fetchCurrencyList()
  topSelector.addEventListener('change', convert)
  bottomSelector.addEventListener('change', convert)
  input.addEventListener('keyup', convert)
})

function fetchCurrencyList() {
  return fetchJson(baseUrl + topSelector.value).then((data) => {
    data.rates[data.base] = 1
    for (const currency in data.rates) {
      const optionItem = document.createElement('option')
      const optionItem2 = document.createElement('option')
      optionItem.text = currency
      optionItem.value = data.rates[currency]
      optionItem2.text = currency
      optionItem2.value = data.rates[currency]
      topSelector.appendChild(optionItem)
      bottomSelector.appendChild(optionItem2)
    }
    convert()
  })
}

function convert() {
  const bottomSelectValue = bottomSelector.value
  const topSelectValue = topSelector.value

  converted.value = parseFloat(
    topSelectValue * input.value / bottomSelectValue
  ).toFixed(2)

  if (!converted.value || isNaN(converted.value)) {
    converted.value = 'Please Enter A Number'
  }
}

function fetchJson(url) {
  return fetch(url)
    .then((response) => {
      return response.json()
    })
}
html {
	font-family: "Lato", sans-serif;
	font-weight: thin;
	background-image: linear-gradient(to right top, #90d0ff, #008ef7);
	color: white;
	height: 100vh;
	overflow: hidden;
}
.container {
	width: 100%;
	height: 80%;
	display: flex;
	align-items: center;
	flex-direction: column;
	text-align: center;

	justify-content: center;
	align-items: center;
}

.container input {
	background: transparent;
	border: none;
	border-bottom: 0.1vh solid white;
	font-size: 2em;
	max-width: 100%;
	outline: none;
	font-family: "Lato", sans-serif;
	font-weight: thin;
	color: white;
	text-align: center;
	overflow: visible;
}
::placeholder {
	/* Chrome, Firefox, Opera, Safari 10.1+ */
	color: white;
	opacity: 1;
	/* Firefox */
}

:-ms-input-placeholder {
	/* Internet Explorer 10-11 */
	color: white;
}

::-ms-input-placeholder {
	/* Microsoft Edge */
	color: white;
}

.container select {
	background: transparent;
	color: white;
  padding: 0px 14px;
	width: 80px;
	height: 30px;
	border: none;
	font-size: 14px;
	box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
	-webkit-appearance: button;
	outline: none;
	margin-top: 1%;
}
.converted {
	pointer-events: none;
	margin-top: 5%;
}
 
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<title>Currency Converter</title>
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<link rel="stylesheet" href="main.css" />
		<link
			href="https://fonts.googleapis.com/css?family=Lato:300&display=swap"
			rel="stylesheet"
		/>
	</head>

	<body>
	<div class="container" id="ctn1">
				<input type="text" id="input" autocomplete="off" placeholder="Enter your number" onfocus="this.placeholder = ''" onblur="this.placeholder ='Enter your number'"/>

				<select id="top-select"> </select>
			<div class="container" id="ctn2">
				<input type="text" class="converted" id="converted" autocomplete="off" placeholder="0.00" />
				<select id="bottom-select"> </select>
			</div>
		
		<script src="main.js"></script>
	</body>
</html>

编辑:原始代码上还有其他错误应该修复,因此我已编辑了代码段以使其按预期工作。为比率而不是2个数组使用对象比较理想,因为在索引号上进行传递非常冒险。

答案 1 :(得分:0)

不确定我是否完全理解。

我在这里要做的是将value属性添加到option标记,并将其推送到currencyArr,我猜这会更改端点。

let currencyArr = [];
let ratesArr = [];
window.addEventListener("load", () => {
    let api = "https://api.exchangeratesapi.io/latest?base=";
    fetch(api)
        .then(response => {
            return response.json();
        })
        .then(data => {
            for (currency in data.rates) {
                currencyArr.push(currency);
                ratesArr.push(data.rates[currency]);

                // create 'option' element here
                const optionTop = document.createElement("option");
                const optionRight = document.createElement("option");
                optionTop.textContent = currency;
                optionRight.textContent = currency;
                /* Changed code */
                optionRight.value = currency;
                optionTop.value = currency;
                /* End here */
                document.querySelector("#top-select").appendChild(optionTop);
                document.querySelector("#bottom-select").appendChild(optionRight);
            }

            document.querySelector("#input").addEventListener("keyup", convert);
            document
                .querySelector("#bottom-select")
                .addEventListener("change", convert);

            function convert() {
                const input = document.querySelector("#input");
                let bottomSelectValue = document.querySelector("#bottom-select").value;

                for (let i = 0; i < currencyArr.length; i++) {
                    if (bottomSelectValue === currencyArr[i]) {
                        document.querySelector("#converted").value = parseFloat(
                            ratesArr[i] * input.value
                        ).toFixed(2);
                    }
                    if (isNaN(document.querySelector("#converted").value)) {
                        document.querySelector("#converted").value =
                            "Please Enter A Number";
                    }
                }
            }
        });
});

这样,您可以轻松知道单击了哪个选项标签以及发送什么值。