【问题标题】:document.querySelector causing errors on other methods when calleddocument.querySelector 在调用时导致其他方法出错
【发布时间】:2021-12-01 06:38:00
【问题描述】:

对于这个愚蠢的问题,我深表歉意,但我正在尝试在上传文件时更改按钮的名称。我通过 TypeScript 更改它的代码是这样的:

    const i = (document.querySelector('label') as any).innerText = filename;

上面的代码,在fileName 方法中,将“上传项目文件”文本更改为上传的任何文件的名称。

    <div class="row">
      <div class="clg6 cmd8 csm10 cxs12" v-if="this.projectFile">
        <button 
          class="button primary outline medium upload">
          <label>
            <input 
            type="file"
            name="projectFile"
            id="fileName"
            accept=".xls, .xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" 
            v-on:change="validateFileType(); hashContentMD5(); fileName; getPresignedURL()"/>
              <i class="fas fa-cloud-upload"></i> 
              Upload Project File
          </label>
        </button>
      </div>
    </div>

而且它有效。但是,在更改时,它会在我的其他方法被调用时出现错误,例如:

const file = (document.getElementById('fileName')as any).files[0]

出现的错误是

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'files')

删除document.querySelector 会删除错误。这是我第一次遇到这种情况。我该如何解决?

【问题讨论】:

  • 为什么不用ref 而不是document.querySelector?
  • 抱歉,我可能睡眠不足——那会是什么样子? @LucasDavidFerrero
  • 不要在 Vue 中直接访问 DOM,除非你必须(这里你不需要),当然不能通过选择器。您可以通过事件访问输入值,而不是访问元素

标签: html typescript vue.js


【解决方案1】:

问题:

您将input 放在label 标记内。我知道这没关系。

  1. 为什么在整个label 和input 标签之外使用button?我不明白你的意图是什么。
  2. 您将label 标记的内部替换为文本节点(包含文件名)。通过您的替换,您从 DOM 中删除了您的 input 字段。请参阅代码中的 querySelector 行。
  3. 替换输入字段后,页面上没有fileName,所以getElementById结果为null。

解决方案:

  1. (可选)我会删除button 标签,只保留它的内部。
  2. 不要对该label进行操作,也不要尝试覆盖文件input字段的值
  3. 不再删除input字段,您可以访问它并读出文件名

在此处查看我的示例:https://stackblitz.com/edit/js-fdxxnf

【讨论】:

  • 标签输入有什么问题?
  • 把&lt;input&gt;放在&lt;label&gt;里面是没有错的。不使用 ID 的另一种标签关联方式。
  • 对不起,我错了,你是对的,直到今天我才这样使用标签。
【解决方案2】:

你可以试试ref:

new Vue({
  el: '#demo',
  data() {
    return {
      projectFile: true
    }
  },
  methods: {
    changeLbl() {
      this.$refs.lab.innerText = 'filename'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div class="row">
      <div class="clg6 cmd8 csm10 cxs12" v-if="projectFile">
        <button 
          class="button primary outline medium upload">
          <label ref="lab">
            <input 
            type="file"
            name="projectFile"
            id="fileName"
            accept=".xls, .xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" 
            v-on:change="changeLbl"/>
              <i class="fas fa-cloud-upload"></i> 
              Upload Project File
          </label>
        </button>
      </div>
  </div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    相关资源
    最近更新 更多