1、今天尝试完成昨天遗留的计算器作业,没想到进入太多的坑。
- 关于document.getElementById(‘ID’).value方法需要注意的情况
- onclick、onchange等事件的触发机制
- 浮点数的运算精确度
下面通过代码片段来慢慢解释:
关于document.getElementById('ID').value
//html
<div id="caculator">
<input type="text" value="123456" id="test" />
</div>
//js代码1
console.log(test);//输出<input type="text" value="123456" id="test" />
🔺变量test虽然没有被定义,但是test是html元素的ID,在这种情况下js默认输出该ID所包含的元素块(见图片1);如果此时使用alert(test)或.innerHTML来进行输出其value的话,输出的字符为:[object HTMLInputElement]或者类似;如果页面中没有test这个Id的HTML元素的话,控制台能看到报错信息:Uncaught ReferenceError: test is not defined.
//js代码2
var test = document.getElementById('test').value;
function charTest() {
console.log(test);
}
charTest();//输出123456
🔺变量test与Html元素Id相同,但是这里被重新声明过了,用来指代该元素的value,所以才能输出数值字符串;
🔺算然声明定义了test变量,但是该变量依托HTML页面中ID为test的元素块的内容;如果该ID被删除或者改写,控制台中仍然会报错:Uncaught TypeError: Cannot read property 'value' of null。这应该是value方法的缘故吧。
下面贴出整个计算器页面布局的HTML部分:
<div id="caculator">
<input id="num1" type="number" value="0" placeholder="请输入第一个数字" />
<br>
<input id="num2" type="number" value="0" placeholder="请输入第二个数字" />
<br>
<button id="jia" type="button">➕</button>
<button id="jian" type="button">➖</button>
<button id="cheng" type="button">✖</button>
<button id="chu" type="button">➗</button>
<br>
<p>计算结果为:<span id="result"></span></p>
</div>
//下面贴出该计算器可运行的js代码块
var data1 = data2 = 0;
document.getElementById('num1').onchange = function() {
data1 = document.getElementById('num1').value * 1;
};
document.getElementById('num2').onchange = function() {
data2 = document.getElementById('num2').value * 1;
};
document.getElementById('jia').onclick = function() {
calculator('+');
}
document.getElementById('jian').onclick = function() {
calculator('-');
}
document.getElementById('cheng').onclick = function() {
calculator('*');
}
document.getElementById('chu').onclick = function() {
calculator('/');
}
function calculator(method) {
console.log(data1, data2);
switch (method) {
case '+':
document.getElementById('result').innerHTML = parseFloat((data1 + data2).toFixed(100));
break;
case '-':
document.getElementById('result').innerHTML = parseFloat((data1 - data2).toFixed(100));
break;
case '*':
document.getElementById('result').innerHTML = parseFloat((data1 * data2).toFixed(100));
break;
case '/':
document.getElementById('result').innerHTML = parseFloat((data1 / data2).toFixed(100));
break;
}
}
一个需要注意的问题是,这里的onchange和onclick不是直接写在HTML标签元素上的,也就是没采用下面这样的样式:
<input type="number" onclick="alert('Hello World!');" />
而是使用了类似下面的样式:
document.getElementById('ID').onchange = function(){}
这里面onchange\onclick事件写法不同会产生不同的结果
<input id="btn" type="button" value="点我弹窗" onclick="alert('hello world')">
🔺上边的写法是单独在元素中绑定事件,这样写是有效的;但是就目前来说,为了SEO效果一般不推荐这么写了
▼如果通过引入的方式来写,则需要写成如下样式,并且在上面的HTML标签里面删除已经绑定的onclick事件,否则因为同时执行两个事件,JS会不做任何操作,即使两个事件是完全相同的。
<script>
document.getElementById("btn").onclick = function() {
alert('hello world');
}
</script>
🔺但是有一个疑问上面的为何不能直接写成下面的样式:
document.getElementById("btn").onclick = alert('hello world');
//当使用上面的写法时,alert在HTML文档打开之后就立即执行了,而不是依托于onclick事件,难道这个=号右边的alert方法被当成了赋值?而.onclick被当成了一个对象属性?下面再写一个例子来验证:
var e = '';
var getSum = function(e) {
alert('你的名字是:' + e );
} //在使用function(){}包裹之后 alert并没有运行;此时getSum的类型是function,!!!!!是需要等待被执行的!!!!!!
var getSum = alert('我来进行求和运算');//解除function(){}包裹之后,alert在文档载入后就立即运行了。此时getSum的类型是undefined;有没有他无所谓;alert本身不是一个值,与prompt不同,prompt可以进行赋值,与之对应的对象类型是string;
可能我需要了解function这个关键字的含义和用法?事件绑定在标签元素上和作为引用的写法有所不同。上面的例子如果是下面的写法,则能够与事件绑定,达成要求的效果。
<input id="btn" type="button" value="点我弹窗" onclick="getSum('张三')">
以上总结,prompt
、alert
、console
等输入输出方法可以直接运行,前面也可以加变量,但是除了prompt
之外,另外两个输出的方法加变量似乎没有什么意义。onclick事件的使用方法见 this page,引用的方法如下2种:
object.onclick = function(){
// my script;
}
或者:
object.addEventListener('click',myScript);//IE8及更早不支持
最后是关于浮点运算的,之前看到的在加法运算时乘以10再除以10的方案局限性太明显,只能用在小数点后一位吧?现在可以用tofix()来解决这个问题了,使用的方式参照parseFloat((运算表达式).toFixed(10))
10代表小数点后取的位数。