问题描述
我的 HTML 中有一个 <input type="file" id="browse-button"/> 文件浏览器输入.
我有另一个 ID 为 choose-file-button 的按钮,单击该按钮时会调用 document.getElementById("browse-button").click();.单击此按钮时,它会正确单击 #browse-button 并打开文件对话框.
现在,我从 this answer 获取代码来拦截 Ctrl+O 按键和打开我的文件对话框,所以我有这个:
$(window).bind('keydown', function(e){if (e.ctrlKey || e.metaKey){开关 (String.fromCharCode(e.which).toLowerCase()){案例's':e.preventDefault();//这个问题无关紧要返回假;案例o":e.preventDefault();document.getElementById("选择文件按钮").click();返回假;}}返回真;});如您所见,当我拦截 Ctrl+O 时,我点击了我的 #choose-file-button 按钮,该按钮调用了 document.getElementById("browser-button"); 在其 onclick 处理程序中.我在这个点击处理程序中放置了一个断点,当我按下 Ctrl+O 时,它确实到达了这个断点.但是,文件对话框永远不会出现.
通过调试发现,如果我在#choose-file-button click()行后面加上一个alert(...);,那么警告显示和正常页面打开文件"对话框显示(不是我的文件对话框).但是,如果我没有此警报,则根本不会显示任何内容.
这是一个错误吗?如何修复它并通过截获的 Ctrl+O 显示我的文件对话框?
我刚刚在 Chrome 中进行了测试,它运行良好.但是,它仍然无法在 Firefox 中运行.
这里有一些浏览器安全魔法.当使用超时或间隔或我尝试的任何其他方法时,代码照常进行,但浏览器只是拒绝打开文件上传对话框.这可能是故意的,以阻止恶意 JS 在未经同意的情况下尝试抓取用户的文件.但是,如果您绑定到链接上的单击事件,则可以使用 jQuery 或常规 JS 完美运行.
正如怀疑的那样,大多数浏览器会根据事件的类型以及它是由用户创建还是以编程方式生成来跟踪事件是否可信.请参阅 this answer 了解完整详情.如您所见,由于键盘事件不在列表中,因此它们永远不能被信任.
测试 JSFiddle
<form action="#" method="post"><input type="file" id="myfile" name="myfile"/><a href="#" id="mylink" accesskey="o">点我</a></div></表格>$("#mylink").click(function () {$("#myfile").click();});$(window).bind('keydown', function (e) {如果(e.ctrlKey || e.metaKey){switch (String.fromCharCode(e.which).toLowerCase()) {案例o":e.preventDefault();控制台.log("1a");$("#myfile").click();//警报(你好");控制台.log("1b");返回假;}}返回真;});我认为这里只有两个选项,它们都是变通方法,而不是解决方案.
- 一种是使用链接触发文件上传对话框,并要求人们使用 ALT+SHIFT+O 而不是 CTRL+O(因为我添加了一个
accesskey 属性到示例中的链接). - 另一种选择是为 拖放文件上传.
附录:我还尝试在 Firefox 中使用纯 JavaScript 来获取点击事件,并使用 isTrusted 属性检查它是否受信任.对于链接上的点击,它返回 true.但是,尝试在其他地方存储和重用该事件是行不通的,因为在您获得对它的引用时它已经被分派了.此外,毫不奇怪,创建一个新事件并尝试设置 isTrusted = true 也不起作用,因为它是只读的.
I have an <input type="file" id="browse-button"/> file-browser input in my HTML.
I have another button with ID choose-file-button that, when clicked, calls document.getElementById("browse-button").click();. When this button is clicked, it correctly clicks #browse-button and the file dialog opens.
Now, I took code from this answer to intercept a Ctrl+O keypress and open my file dialog, so I have this:
$(window).bind('keydown', function(e)
{
if (e.ctrlKey || e.metaKey)
{
switch (String.fromCharCode(e.which).toLowerCase())
{
case 's':
e.preventDefault();
// doesn't matter for this question
return false;
case 'o':
e.preventDefault();
document.getElementById("choose-file-button").click();
return false;
}
}
return true;
});
As you can see, when I intercept Ctrl+O I click on my #choose-file-button button, which calls document.getElementById("browse-button"); in its onclick handler. I have put a breakpoint in this click handler, and when I press Ctrl+O it does arrive at this breakpoint. However, the file dialog never shows up.
Through debugging, I found out that if I put an alert(...); after the #choose-file-button click() line, then the alert shows up and the normal page "Open File" dialog shows up (not my file dialog). If I do not have this alert, however, nothing shows up at all.
Is this a bug? How can I fix it and make my file dialog show up via the intercepted Ctrl+O?
Edit: I just tested in Chrome, and it works perfectly. However, it still does not work in Firefox.
解决方案 There's some browser security magic going on here. When using timeouts or intervals or any other methods I try, the code carries on as normal but the browser simply refuses to open a file upload dialog. This is probably deliberate, to stop malicious JS from trying to grab users' files without consent. However, if you bind to a click event on a link, it works perfectly using jQuery or regular JS.
Edit: As suspected, most browsers keep track of whether an event is trusted or not based on the type of event and whether it was created by the user or generated programmatically. Se this answer for the full details. As you can see, since keyboard events aren't in the list, they can never be trusted.
Test JSFiddle
<form action="#" method="post">
<div>
<input type="file" id="myfile" name="myfile" /> <a href="#" id="mylink" accesskey="o">Click me</a>
</div>
</form>
$("#mylink").click(function () {
$("#myfile").click();
});
$(window).bind('keydown', function (e) {
if (e.ctrlKey || e.metaKey) {
switch (String.fromCharCode(e.which).toLowerCase()) {
case 'o':
e.preventDefault();
console.log("1a");
$("#myfile").click();
//alert("hello");
console.log("1b");
return false;
}
}
return true;
});
I think there are only two options here, and they're both workarounds, not solutions.
- One is to use a link to trigger the file upload dialog, and ask people to use ALT+SHIFT+O instead of CTRL+O (because I added an
accesskey attribute to the link in the example).
- The other alternative is to use one of the new HTML5 JavaScript APIs for drag-drop file uploading.
Addendum: I also tried using pure JavaScript in Firefox to grab a click event and check to see if it's trusted using the isTrusted property. For the clicks on the link, it returned true. However, attempting to store and re-use the event elsewhere doesn't work, because it's already been dispatched by the time you get a reference to it. Also, unsurprisingly, creating a new event and attempting to set isTrusted = true doesn't work either since it's read-only.
这篇关于Javascript 拦截“Ctrl+O"不打开我的文件对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!
The End
相关推荐
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22
前端开发问题
182
主页面上显示了一个合计,在删除和增加的时候需要更改这个总套数的值: //html代码div class="layui-inline layui-show-xs-block" style="margin-left: 10px" id="sumDiv"spanSOP合计:/spanspan${totalNum}/spanspan套/span/div 于是在我们删除这个条数据后,...
2024-11-14
前端开发问题
156
问题描述 我想改变layui时间日历布局大小,这个要怎么操作呢? 解决办法 可以用css样式对时间日历进行重新布局,具体代码如下: !DOCTYPE htmlhtmlheadmeta charset="UTF-8"title/titlelink rel="stylesheet" href="../../layui/css/layui.css" /style#test-...
2024-10-24
前端开发问题
271
layui中表单会自动刷新的问题,因为用到layui的表单,遇到了刷新的问题所以记录一下: script layui.use(['jquery','form','layer'], function(){ var $ = layui.jquery, layer=layui.layer, form = layui.form; form.on('submit(tijiao)', function(data){ a...
2024-10-23
前端开发问题
262
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18
前端开发问题
301
append() 方法在被选元素的结尾(仍然在内部)插入指定内容。 语法: $(selector).append( content ) var creatPrintList = function(data){ var innerHtml = ""; for(var i =0;i data.length;i++){ innerHtml +="li class='contentLi'"; innerHtml +="a href...
2024-10-18
前端开发问题
125
热门文章
1错误 [ERR_REQUIRE_ESM]:不支持 ES 模块的 require()
2vue中yarn install报错:info There appears to be trouble with you
3为什么 Chrome(在 Electron 内部)会突然重定向到 chrome-error://chromewebdat
4“aria-hidden 元素不包含可聚焦元素"显示模态时的问题
5使用选择器在 CSS 中选择元素的前一个兄弟
6js报错:Uncaught SyntaxError: Unexpected string
7layui怎么刷新当前页面?
8将模式设置为“no-cors"时使用 fetch 访问 API 时出错
热门精品源码
最新VIP资源
1多功能实用站长工具箱html功能模板
2多风格简历在线生成程序网页模板
3论文相似度查询系统源码
4响应式旅游景点宣传推广页面模板
5在线起名宣传推广网站源码
6酷黑微信小程序网站开发宣传页模板
7房产销售交易中介网站模板
8小学作业自动生成程序




大气响应式网络建站服务公司织梦模板
高端大气html5设计公司网站源码
织梦dede网页模板下载素材销售下载站平台(带会员中心带筛选)
财税代理公司注册代理记账网站织梦模板(带手机端)
成人高考自考在职研究生教育机构网站源码(带手机端)
高端HTML5响应式企业集团通用类网站织梦模板(自适应手机端)