gpt4 book ai didi

javascript - 从文本文件读取而不使用 JavaScript 中的事件

转载 作者:行者123 更新时间:2023-12-03 11:53:40 25 4
gpt4 key购买 nike

以下内容在触发并选择文件时起作用,但在这种情况下我什至不想使用该事件,我希望文件从路径自动加载并逐行读取。

<input type="file" id="fileinput" />
<script>
function readSingleFile(evt){

//Retrieve the first (and only!) File from the FileList object
var f = evt.target.files[0];

if(f){
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
// Some code
}
r.readAsText(f);
}else{
alert("Failed to load file");
}
}
document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
<script>

最佳答案

从用户操作系统加载文件必须由某种形式的用户事件触发,除了从 Canvas 元素获取文件对象(可以直接生成)。

如这个excerpt from MDN状态:

File objects may be obtained from a FileList object returned as a result of a user selecting files using the element, from a drag and drop operation's DataTransfer object, or from the mozGetAsFile() API on an HTMLCanvasElement.

在没有用户干预或明确许可的情况下,允许网页能够从用户计算机加载任何文件,这确实是一件危险的事情。但是,根据您可以对文件(或主机环境)执行的操作,您确实有一些选择。


通过 AJAX/XHTTP 加载文件

我包含了通过 file:// 协议(protocol)使用的源代码,因此在本地下载 jQuery,而不是使用任何等效的热链接。为了测试这一点,您只需下载 jQuery 并将其保存在与此 HTML 文件相同的目录中,显然可以创建一个 textfile.txt 或更改代码以指向另一个文件。

NOTE: The file path should be kept within your web root and accessible from your web server under the same host, unless you are running the code from the file:// protocol locally. If you are running over the file:// protocol, you can load a file from anywhere on your machine as long as your browser has permissions to access said file, and you remain accessing via file://.

以这种方式加载文件(或我在页面上提到的任何其他方法)与您在问题中加载文件的方式存在很大差异。通过文件选择器对话框加载文件是从用户自己的计算机获取文件;而通过 AJAX(或通过 script/iframe 标签)加载文件则是从服务器获取文件。这是否会违背你的目标取决于你到底用它做什么。尽管如此,加载文本文件最好通过此方法完成,下面您将发现其他一些辅助方法,它们确实有其优点,但也有许多缺点。

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Load a text file</title>
<script src="jquery.js"></script>
<script>
jQuery
.ajax({
url: 'textfile.txt',
dataType: 'text'
})
.error(function(){
console.warn('An error occurred whilst loading the file', arguments);
})
.done(function(res){
jQuery.each(res.split(/\r?\n/g), function(i, v){
jQuery('#output').append('<p>' + v + '</p>');
});
})
;
</script>
</head>
<body>
<h1>Fileload</h1>
<div id="output"></div>
</body>
</html>


通过脚本标签加载文件

此选项要求您将文本文件修改为由一小段 JavaScript 封装,然后这将允许您使用普通脚本标记导入其内容。与 AJAX 不同,它不受跨源阻塞的影响,即 stackoverflow.com 可以从 gamedev.stackexchange.com 请求文件。此方法还具有占用空间很小的优点。

NOTE: AJAX requests can now reliably get around the cross-origin problems when implementing CORS. However this does usually involve having some control of the server-side.

这种方法的缺点是你必须修改你的文本文件,你的文本文件被解析为 JavaScript(意味着某些高阶字符可能会扰乱旧的解析器),并且你正在滥用 Function.toString() 。如果您对使用多行黑客的注释不满意,您可以轻松地将文本文件修改为 implement multiline strings the proper way using string concatenation instead 。但是一旦你这样做了,你就离加载纯文本文件之类的东西就很远了。

文本文件的内容

(typeof loadfile != 'undefined') && loadfile(function(){/*
Place your text file contents here.
We are abusing the JavaScript comment facility
to achieve multiline strings without too much
modification to your original text file.
*/});

主页中的脚本

<script>
/**
* This function is responsible for receiving the function
* sent by your text file
*/
function loadfile(content){
var text = String(content && content.toString()),
p1 = text.indexOf('/*')+2,
p2 = text.lastIndexOf('*/')
;
console.log(text.substring(p1, p2));
};
</script>
<script src="your-text-file.txt.js"></script>


通过 iframe 加载文件

在 AJAX 流行之前,如果没有可用的服务器端,此选项几乎就是常用的选项。与 AJAX 相比,它实际上没有任何优势,除了以下事实:如果使用轮询来监视 iframe 何时准备就绪,则管理 iframe 的代码会更小并且跨浏览器更可靠。对于 AJAX,通常最好依靠库(如 jQuery)来处理不同环境之间的差异。

但是,AJAX 为您提供了更多的能力,以及关于何时发生的事情的更多交互式反馈(对事件有更好的支持)。依赖轮询可能会更慢/不可靠,但这是使用 iframe 的唯一选择,因为并非所有浏览器都支持触发正确的事件,尤其是在处理意外的数据类型时。

这是我曾经使用过的一个脚本,我已经对其进行了整理和更新,只是为了说明这一点。此版本依赖于 Object.create so you will need a polyfill如果您想在旧版浏览器中使用它;但正如我多次说过的...如果可以的话,请使用 AJAX,如果不能,那么也许您的方法需要重新考虑。

/**
* Textfile
*
* Allows the loading of a textfile via an iframe or script tag.
*
* Loading via script tag:
*
* textfile.load({
* type: 'script',
* path: 'textfile.txt.js'
* })
* .fail(function(){
* console.log('an error occured!');
* })
* .done(function(res){
* console.log('file loaded', res);
* })
* ;
*
* loading via iframe:
*
* textfile.load({
* type: 'iframe',
* path: 'textfile.txt'
* })
* .fail(function(){
* console.log('an error occured!');
* })
* .done(function(res){
* console.log('file loaded', res);
* })
* ;
*
* NOTE: When loading via a script tag, your text file must be in the
* following format:
*/
(typeof textfile != 'undefined') && textfile.injected('NAME OF YOUR FILE', function(){/*
This is example text content
you can have as many lines as
you want.
*/});
/**
* Once your text file is wrapped with the above the textfile code
* will be notified that the file has been loaded, and it will also
* allow you to have multiline text more easily in JavaScript.
*
* <NAME OF YOUR FILE> should be replaced with your filename to load
* for example textfile.txt.js
*/
var textfile = (function(){

var tf = {

shared: {},

create: function(config){
return tf.prep.apply(Object.create(tf), arguments);
},

prep: function(config){
this.config = config;
this.tag = !this.config.inline
? document.documentElement
: document.scripts[document.scripts.length-1]
;
this.tid = setTimeout(this.bind(this.timeout), this.config.timeout || 5 * 1000);
this.iid = setInterval(this.bind(this.polling), 100);
this.loader = this.config.type === 'script'
? this.script()
: this.frame()
;
this.loader.src = this.config.path;
!this.config.inline
? this.tag.appendChild(this.loader)
: this.tag.parentNode && this.tag.parentNode.insertBefore(this.loader, null)
;
return this;
},

script: function(element){
if ( element ) { return element; }
element = document.createElement('script');
element.type = 'text/javascript';
return element;
},

frame: function(element){
if ( element ) { return element; }
element = document.createElement('iframe');
element.style.position = 'fixed';
element.style.right = '100%';
element.style.bottom = '100%';
element.style.width = '1em';
element.style.height = '1em';
return element;
},

tidyup: function(){
this.loader && this.loader.parentNode.removeChild(this.loader);
return this;
},

loaded: function(res){
this.trigger('done', res);
this.tidyup();
return this;
},

failed: function(){
this.trigger('fail');
this.tidyup();
return this;
},

on: function(name, listener){
!this.listeners && (this.listeners = {});
!this.listeners[name] && (this.listeners[name] = []);
this.listeners[name].push(listener);
return this;
},

off: function(name, listener){
if ( this.listeners && this.listeners[name] ) {
for ( var a=this.listeners[name], i=a.length-1; i>=0; i-- ) {
if ( a[i] === listener ) {
this.listeners[name].splice(i, 1);
}
}
}
return this;
},

trigger: function(name, data, context){
if ( this.listeners && this.listeners[name] ) {
for ( var i=0, a=this.listeners[name], l=a.length; i<l; i++ ) {
if ( a[i] && a[i].call ) {
a[i].call( context || this, data );
}
}
}
return this;
},

bind: function(method, args, context){
!context && args && !args.length && (context = args);
!context && (context = this);
args && (args = Array.prototype.slice.call(args));
return function(){
return (args
? method.apply(context, args.concat(Array.prototype.slice.call(arguments)))
: method.apply(context, arguments)
);
};
},

fail: function(listener){ return this.on('fail', listener); },
done: function(listener){ return this.on('done', listener); },

timeout: function(){
clearInterval(this.iid);
this.failed();
},

polling: function(){
var obj, text, ex;
if ( this.config.type === 'iframe' ) {
try { text = ((obj=this.loader.contentWindow) && obj.document.documentElement.textContent) ||
((obj=this.loader.contentWindow) && obj.document.documentElement.innerText) ||
((obj=this.loader.contentDocument) && obj.documentElement.textContent) ||
((obj=this.loader.contentDocument) && obj.documentElement.innerText);
} catch (ex) {}
}
else {
text = this.loader.textContent ||
this.loader.text ||
this.loader.innerHTML ||
this.shared.loaded && this.shared.loaded[this.config.path]
;
}
if ( text && text.split ) {
this.loaded(text);
clearInterval(this.tid);
clearInterval(this.iid);
}
},

injected: function(script, content){
var text = String(content && content.toString()),
p1 = text.indexOf('/*')+2,
p2 = text.lastIndexOf('*/')
;
!this.shared.loaded && (this.shared.loaded={});
this.shared.loaded[script] = text.substring(p1, p2);
},

load: function(config){
return config && config.split
? tf.create({ path: config })
: tf.create(config)
;
}

};

return tf;

})();

关于javascript - 从文本文件读取而不使用 JavaScript 中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25699302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com