自定义input[type="file"]的兼容样式

本文介绍了一种解决input[type=file]在不同浏览器中样式不一致的问题的方法,通过自定义样式和利用绝对定位与透明度控制,实现了跨浏览器的一致表现。

input[type="file"]的样式在各个浏览器中的表现不尽相同:

1. chrome:

2. firefox:

3. opera:

4. ie:

5. edge:

另外,当我们规定 input[type="file"] 的高度,并把它的行高设置成与其高度相等后,chrome中难看的样式出现了:


“未选择任何文件”这一行并没有竖直居中。

这些浏览器中的表现不一致,我们必须做兼容处理。

思路:

1. 自定义与其中一个浏览器表现类似的样式,将其放在下层;

2. 将浏览器本身的表现出来的样式“隐藏掉”, opacity:  0; 置于上层,这样我们点击的才是 input[type="file"] 响应的事件;

3. 选择文件或改变文件后,改变显示 file 的值。

<form action="" class="activityForm">
  <div class="file">
    <label for="file">文件:</label>
    <div class="userdefined-file">
      <input type="text" name="userdefinedFile" id="userdefinedFile" value="未选择任何文件">
      <button type="button">上传</button>
    </div>
    <input type="file" name="file" id="file">            
  </div>
</form>
.file {
  position: relative;
  height: 40px;
  line-height: 40px;
}
.file label {
  display: inline-block;
}
.userdefined-file {
  position: absolute;
  top: 0;
  left: 60px;
  z-index: 2;
  width: 300px;
  height: 40px;
  line-height: 40px;
  font-size: 0;  /*应对子元素为 inline-block 引起的外边距*/
}
.userdefined-file input[type="text"] {
  display: inline-block;
  vertical-align: middle;
  padding-right: 14px;
  padding-left: 14px;
  width: 220px;
  box-sizing: border-box;
  border: 1px solid #ccc;
  height: 40px;
  line-height: 40px;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.userdefined-file button {
  display: inline-block;
  vertical-align: middle;
  width: 80px;
  text-align: center;
  height: 40px;
  line-height: 40px;
  font-size: 14px;
  background-color: #f54;
  border: none;
  color: #fff;
  cursor: pointer;
}
.file input[type="file"] {
  position: absolute;
  top: 0;
  left: 60px;
  z-index: 3;
  opacity: 0;
  width: 300px;
  height: 40px;
  line-height: 40px;
  cursor: pointer;
}
document.getElementById("file").onchange = function() {
    document.getElementById("userdefinedFile").value = document.getElementById("file").value;
}

这样处理后,就在各个浏览器中表现一致了:

1. 未选择任何文件时,在 chrome 中:

2. 在选择文件后,在 firefox 中:

  

在使用 `<input type="file" webkitdirectory>` 属性时,浏览器弹出文件选择窗口被拦截的问题通常与用户交互限制或浏览器安全策略有关。以下是几种可能的解决方案: ### 1. 确保触发事件由用户主动发起 大多数现代浏览器要求文件选择操作必须由用户的直接交互(如点击按钮)触发,否则会被视为潜在的恶意行为并加以阻止。可以通过确保 `input` 元素的 `click()` 方法是由用户事件(例如 `click`、`touchstart`)触发的方式来解决。 ```javascript document.getElementById('triggerButton').addEventListener('click', function() { document.getElementById('fileInput').click(); }); ``` ### 2. 使用隐藏的 `<input>` 元素并绑定到可见按钮 通过将 `<input>` 设置为不可见,并将其与一个自定义样式的按钮关联,可以避免因样式问题导致的点击无效情况。 ```html <input type="file" id="fileInput" webkitdirectory style="display: none;" /> <button id="triggerButton">选择文件夹</button> ``` ### 3. 检查浏览器兼容性与权限设置 某些浏览器(尤其是移动端浏览器)可能不完全支持 `webkitdirectory` 或对其有特定限制。需要确认目标浏览器是否支持该属性,并检查是否有相关的扩展或插件干扰了文件选择行为。 ### 4. 使用异步延迟调用以规避弹窗拦截机制 在某些情况下,如果文件选择操作是在非同步事件中触发(如通过 `setTimeout` 或异步回调),浏览器可能会阻止弹窗。可以通过立即执行或在用户事件上下文中直接调用 `click()` 来规避这一问题。 ```javascript document.getElementById('someElement').addEventListener('click', function() { setTimeout(() => { document.getElementById('fileInput').click(); }, 0); }); ``` ### 5. 添加 `change` 事件监听器以处理选中的目录内容 一旦成功打开文件选择窗口并选中目录,可以通过监听 `change` 事件获取所选文件列表,并进行进一步处理。 ```javascript document.getElementById('fileInput').addEventListener('change', function(event) { const files = event.target.files; for (let i = 0; i < files.length; i++) { console.log(files[i].webkitRelativePath); // 输出文件相对路径 } }); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yusirxiaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值