如何让全局元素与函数访问readFileData动态获取的setname和dictionary
本地文件读取后的变量访问问题
代码片段
HTML代码
<form> <input id="newfile" accept='text/plain' type="file" onchange="readFileData(event)" /> </form> ... <p id="description"></p>
JavaScript代码
var setname = ''; function readFileData(event) { file = event.target.files[0]; setname = file.name.split('.')[0]; var reader = new FileReader(); reader.onload = function(e) { dictionary = toDict(e.target.result); } reader.readAsText(file); } desc = document.getElementById('description'); desc.innerHTML = setname function useDictionary(dictionary) { // more code here }
相关说明
useDictionary()会被另一HTML元素的onkeyup事件调用,需要全局可访问- 仅访问本地HTML文件,为单HTML文件项目
- 使用原生JavaScript,不使用预处理器或库
核心问题
- 如何让
desc.innerHTML访问到setname变量? - 如何让
useDictionary()函数访问到dictionary变量?
曾尝试将useDictionary()放入reader.onload块中,但未成功。
解决方案
问题1:让desc.innerHTML获取到setname
你当前代码里desc.innerHTML = setname是在页面加载时执行的,此时setname还是初始的空字符串,而setname要等用户选择文件后才会被赋值。只需把更新innerHTML的操作移到readFileData函数里,在setname赋值后立即执行:
var setname = ''; // 提前获取元素,避免重复查找DOM var desc = document.getElementById('description'); function readFileData(event) { file = event.target.files[0]; setname = file.name.split('.')[0]; // 赋值后立即更新描述文本 desc.innerHTML = setname; var reader = new FileReader(); reader.onload = function(e) { dictionary = toDict(e.target.result); } reader.readAsText(file); } function useDictionary() { // more code here }
问题2:让useDictionary()访问到dictionary
dictionary是在FileReader的异步回调onload里生成的,如果你把useDictionary放在回调里,它会变成局部函数,无法被全局的onkeyup事件调用。解决方法很直接:
- 把
dictionary声明为全局变量(和setname同级) - 在
useDictionary里直接使用这个全局变量,同时加个判断确保变量已被赋值(避免用户还没选文件就触发函数)
修改后的完整JS代码:
// 声明全局变量,初始化明确状态 var setname = ''; var dictionary = null; var desc = document.getElementById('description'); function readFileData(event) { file = event.target.files[0]; setname = file.name.split('.')[0]; desc.innerHTML = setname; var reader = new FileReader(); reader.onload = function(e) { // 给全局变量赋值 dictionary = toDict(e.target.result); } reader.readAsText(file); } function useDictionary() { // 先判断文件是否已读取完成 if (!dictionary) { alert('请先选择并读取文件'); return; } // 这里可以直接使用全局的dictionary变量 // more code here }
额外提醒
- 所有全局变量提前声明,避免隐式全局变量(比如原来的
file最好加上var或let) FileReader是异步操作,必须等onload回调执行完,dictionary才会有有效值,加判断能避免报错
内容的提问来源于stack exchange,提问作者JitteryNutmeg
相关产品推荐
相关产品推荐

