isNaN+获取焦点与失去焦点

本文详细探讨了JavaScript的isNaN()函数用法,涉及类型转换及实际应用场景。通过实例演示如何在表单验证中使用isNaN()检查数字输入,并解析面试题中关于typeof和typeoftypeof的疑惑。同时涵盖了前端开发和数据类型检查的关键知识点。

//isNaN() 判断非数字的,如果不是数字返回true,如果是数字返回false
//注意点:isNaN()方法会进行隐式数据类型类型转换
// console.log(isNaN(10))
// console.log(isNaN(‘66’))
// console.log(isNaN(‘a’))
// console.log(isNaN(‘120px’))
// console.log(isNaN(‘哈哈’))

    /*
        获取表单的值
        + 通过元素.value属性
        获取元素的内容
        + 通过元素.innerHTML
        + 功能
          => 获取元素的内容
          => 可以设置元素内容
    */

    var tel = document.getElementById('tel')
    var des = document.getElementById('des')
    //console.log(des.innerHTML)
    //des.innerHTML = '请输入数字'

    //获取焦点
    // tel.onfocus = function(){
    //     console.log('获取焦点')
    // }
    //失去焦点事件
    tel.onblur = function(){
        var val = tel.value
        var res = isNaN(val)
        if(res){
            //console.log('不是数字')
            des.innerHTML = '你输入的不是数字,请重新输入'
        }else{
            //console.log('输入的是数字')
            des.innerHTML = '恭喜,输入正确√'
        }
    }

    //面试题:typeof typeof num 结果是多少?
    var num = 10
    console.log(typeof num)
    //注意点:先拿到执行结果,number数据类型,针对于这个类型本身就是string,所以结果是string类型,先执行的是后面的值
    console.log(typeof typeof num) //string
    console.log(typeof typeof typeof num) //string

    //console.log(typeof 'number')

    //表示判断数据类型
    console.log(typeof 10 == 'number')
    console.log(typeof 'a' == 'string')
    console.log(typeof true == 'boolean')
import { ref } from 'vue'; export default { setup() { // 实际数值(数字类型) const actualValue = ref(0); // 显示值(字符串) const displayValue = ref('0.00'); // 处理输入事件 const handleInput = (value) => { // 先移除所有非数字和小数点的字符,但注意:不能输入多个小数点 let newValue = value.replace(/[^\d.]/g, ''); // 只保留第一个小数点,去掉后面的 const dotIndex = newValue.indexOf('.'); if (dotIndex !== -1) { // 如果已经有小数点,则后面的小数点都去掉 const beforeDot = newValue.substring(0, dotIndex + 1); const afterDot = newValue.substring(dotIndex + 1).replace(/\./g, ''); newValue = beforeDot + afterDot; } // 限制小数点后最多两位 if (dotIndex !== -1) { const parts = newValue.split('.'); if (parts[1] && parts[1].length > 2) { newValue = parts[0] + '.' + parts[1].substring(0, 2); } } // 更新显示值(此时不带千分符) displayValue.value = newValue; // 更新实际值(转换为数字,如果为空则设为0) actualValue.value = newValue === '' ? 0 : parseFloat(newValue); }; // 处理失去焦点事件:格式化显示 const handleBlur = () => { // 确保actualValue是数字,然后格式化为两位小数 // 注意:如果输入的是整数,我们也要显示两位小数吗?根据需求:涉及金额保留两位小数 // 所以,即使输入整数,也要显示为两位小数 const num = actualValue.value; // 如果输入非法,则用0代替 if (isNaN(num)) { actualValue.value = 0; displayValue.value = formatNumber(0); } else { // 确保两位小数(四舍五入) actualValue.value = Math.round(num * 100) / 100; displayValue.value = formatNumber(actualValue.value); } }; // 处理获取焦点事件:去掉千分符,变成纯数字字符串(但保留两位小数,因为输入时可能需要修改) const handleFocus = () => { // 将显示值变为不带千分符的数字字符串 // 注意:因为失去焦点时已经格式化为两位小数,所以这里直接用actualValue的数值转字符串可能不够两位小数,所以我们要转换为两位小数的字符串 const num = actualValue.value; displayValue.value = num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 但是,我们要去掉千分符,并且显示两位小数吗? // 实际上,在输入时我们希望用户看到的是数字字符串(不带逗号),所以我们要去掉逗号 // 同时,要保证小数部分有两位(如果不足则补0) // 但我们也可以直接显示去掉逗号的字符串,小数部分按实际显示(输入时用户自己输入小数) // 这里我们去掉逗号,并且保留原有小数位数(最多两位,因为输入时已经控制了) // 注意:用户可能输入整数,所以这里要补两位小数吗?不,在输入过程中用户自己输入,我们不需要补。但是在失去焦点时我们会补。 // 所以,获取焦点时,我们去掉逗号,但不补小数位(因为用户可能想修改整数部分) // 因此,我们直接用去掉逗号的字符串,但注意,这个字符串是之前输入时保留的,小数部分可能不足两位,但没关系。 displayValue.value = displayValue.value.replace(/,/g, ''); }; // 格式化数字为千分符并保留两位小数 const formatNumber = (num) => { // 使用toLocaleString方法 return num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }; return { displayValue, actualValue, handleInput, handleBlur, handleFocus }; } };
11-12
<template> <el-input v-model="displayValue" @input="handleInput" @blur="formatDisplayValue" @focus="resetDisplayValue" placeholder="" :maxlength="displayValue.toString().includes('.')?21:18" /> </template> <script> import { ref, watch } from 'vue'; export default { props: { modelValue: { type: String, default: '' } }, emits: ['update:modelValue'], setup(props, { emit }) { // 显示值(带千分符的字符串) const displayValue = ref('') // 实际存储的数值(数字类型) const numericValue = ref(props.modelValue) // 初始化格式 const initFormat = () => { displayValue.value = formatNumber(numericValue.value) } // 数值格式化函数(添加千分符) const formatNumber = (num) => { // return num.toLocaleString('en-US', { // minimumFractionDigits: 2, // maximumFractionDigits: 2 // }) //return num.toLocaleString('en-US', {}) //return num?.toString()?.replace(/(\d)(?=(\d{3})+\.)/g, '$1,') // 处理带小数点的数字 if (num.toString().includes('.')) { const [integerPart, decimalPart] = num.split('.'); return `${integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}.${decimalPart}`; } // 处理整数 return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')+'.00'; } // 输入处理函数 const handleInput = (value) => { // 1. 移除非数字和小数点字符 let filtered = value.replace(/[^\d.]/g, '') // 2. 处理多个小数点的情况 const dotCount = (filtered.match(/\./g) || []).length if (dotCount > 1) { const firstDotIndex = filtered.indexOf('.') filtered = filtered.substring(0, firstDotIndex + 1) + filtered.substring(firstDotIndex + 1).replace(/\./g, '') } // 3. 限制小数点后最多两位 const dotIndex = filtered.indexOf('.') if (dotIndex !== -1 && filtered.length - dotIndex > 3) { filtered = filtered.substring(0, dotIndex + 3) } // 小数点前的数字不能超过18位 if (dotIndex !== -1 && dotIndex > 18) { filtered = filtered.substring(0, 18)+filtered.substring(dotIndex, filtered.toString().length) } // 4. 更新显示值 displayValue.value = filtered // 5. 更新实际数值(转换为数字) //numericValue.value = parseFloat(filtered || 0) || 0 numericValue.value = filtered || 0 emit('update:modelValue', numericValue.value) } // 失去焦点时格式化显示 const formatDisplayValue = () => { // 确保数值有效 //const num = isNaN(numericValue.value) ? numericValue.value : numericValue.value // numericValue.value = parseFloat(num.toFixed(2)) //numericValue.value = num // 添加千分符 displayValue.value = formatNumber(numericValue.value) emit('update:modelValue', numericValue.value) } // 获得焦点时移除千分符 const resetDisplayValue = () => { displayValue.value = numericValue?.value?.toString() } // 监听外部传入值的变化 watch(() => props.modelValue, (newVal) => { if (newVal !== numericValue.value) { numericValue.value = newVal displayValue.value = formatNumber(newVal) } }) initFormat() return { displayValue, handleInput, formatDisplayValue, resetDisplayValue } } } </script>
11-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值