【问题标题】:document.querySelector(...) is null errordocument.querySelector(...) 为空错误
【发布时间】:2013-12-10 13:33:34
【问题描述】:

对于 cakephp 项目中的图像上传,我使用了 java-script。我在 app\View\Layouts default.ctp 中添加了这个 js 文件

js代码

document.querySelector('input[type=file]').addEventListener('change', function(event){

  var files = event.target.files;

  for (var i = 0; i < files.length; i++) {

    if (files[i].type.match(/image.*/)) {

        var reader = new FileReader();
        reader.onload = function (readerEvent) {
            var image = new Image();
            image.onload = function (imageEvent) {

                var imageElement = document.createElement('div');
                imageElement.classList.add('uploading');
                imageElement.innerHTML = '<span class="progress"><span></span></span>';
                var progressElement = imageElement.querySelector('span.progress span');
                progressElement.style.width = 0;
                document.querySelector('form div.photos').appendChild(imageElement);


                var canvas = document.createElement('canvas'),
                    max_size = 1200,
                    width = image.width,
                    height = image.height;
                if (width > height) {
                    if (width > max_size) {
                        height *= max_size / width;
                        width = max_size;
                    }
                } else {
                    if (height > max_size) {
                        width *= max_size / height;
                        height = max_size;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                canvas.getContext('2d').drawImage(image, 0, 0, width, height);

                var xhr = new XMLHttpRequest();
                if (xhr.upload) {

                    // Update progress
                    xhr.upload.addEventListener('progress', function(event) {
                        var percent = parseInt(event.loaded / event.total * 100);
                        progressElement.style.width = percent+'%';
                    }, false);


                    xhr.onreadystatechange = function(event) {
                        if (xhr.readyState == 4) {
                            if (xhr.status == 200) {

                                imageElement.classList.remove('uploading');
                                imageElement.classList.add('uploaded');
                                imageElement.style.backgroundImage = 'url('+xhr.responseText+')';

                                console.log('Image uploaded: '+xhr.responseText);

                            } else {
                                imageElement.parentNode.removeChild(imageElement);
                            }
                        }
                    }

                    xhr.open('post', 'process.php', true);
                    xhr.send(canvas.toDataURL('image/jpeg'));

                }

            }

            image.src = readerEvent.target.result;

        }
        reader.readAsDataURL(files[i]);
    }

}

event.target.value = '';

我检查了没有问题。

现在在 add.ctp 文件中我加法器

<input type="file" multiple />

在输出中,我看到了文件类型字段。现在,当我单击此字段并上传图片时,mojila 错误给了我一个错误。那是

document.querySelector(...) 为空错误

我不知道这个错误。在这里为什么说 queryselector 为空?

【问题讨论】:

  • 说它是null,因为传递给document.querySelector() 的选择器没有返回可以工作的元素/节点。你能验证元素存在吗?如果您可以发布相关的(最小/SSCCE)HTML,那么我们或许能够提供更具体的帮助。
  • 你的意思是没有找到 ?
  • 我的意思是它没有找到与您传递给它的 CSS 选择器匹配的元素。但是您已经在两个不同的地方调用它(querySelector('span.progress span');querySelector('form div.photos')),它们都没有试图找到 any type 的输入。
  • 我刚刚编辑了格式化问题。代码中缺少第一行。这是您正在寻找的选择,@DavidThomas。
  • 好吧,准确计算出 行正在生成错误,并且那是(至少一个)导致错误的行。如果没有找到该元素,那是因为选择器错误,或者该元素在 JavaScript 运行时不存在。

标签: javascript


【解决方案1】:

document.querySelector() 的行为类似于 jQuery.(document).ready() 方法。当 DOM 准备好时,选择器返回对象。

我建议你把所有的JS脚本都调用到页面底部。

【讨论】:

  • 最好的方法是使用 async 或 defer 属性将所有脚本调用放在 &lt;head&gt; 标记中。这会在不阻塞浏览器的情况下下载脚本文件。
  • 不同之处在于async 仅将脚本作为非阻塞网络传输加载,但一旦检索到就会立即执行,而defer 属性表示没有关于如何加载脚本的内容,但将不会立即执行它,而是在 DOM 被解析后执行它(但 DOMContentLoaded 事件被调度之前)。在跨浏览器支持方面,从 IE 10 开始,两者都得到了普遍支持。
  • 对于使用 Vue3 的 ppl,请将其放入 onMounted()
【解决方案2】:

为确保您的 DOM 准备就绪,您可以将其添加到您的 JS 文件中。

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.querySelector('input[type=file]')
        .addEventListener('change', function(event){
            ...
         }
});

这样你可以从任何你喜欢的地方调用你的 js 文件。请查看this superb answer 以进一步了解这些问题。

还可以查看this other Google rule

【讨论】:

    【解决方案3】:

    file.js

    const heading1 = document.querySelector(".heading1");
    console.log(heading1);
    

    解决方案 1


    使用defer(最佳和推荐方式):

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <script src="./file.js" defer></script>
        <title>Document</title>
    </head>
    <body>
        <h1 class="heading1">Hello World 1</h1>
    </body>
    </html>
    

    解决方案 2

    在关闭body标签之前将你的JavaScript放在底部

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Document</title>
    </head>
    <body>
        <h1 class="heading1">Hello World 1</h1>
    
        <script src="./file.js"></script>
    </body>
    </html>
    

    【讨论】:

      【解决方案4】:

      我建议在正文中,在结束标记之前写下你的&lt;script type="text/javascript" src="your js file"&gt;&lt;/script&gt;

      【讨论】:

        【解决方案5】:

        现在有另一种“更好”的方法来解决这个问题。

        将你的脚本放在 head 标签中并添加 defer 属性。

        <!DOCTYPE html>
        <html lang="en">
        <head>
          <title>Document</title>
          <script src="main.js" defer></script>
        </head>
        <body>
          yoyoyo
        </body>
        </html>
        

        您可以在herehere 阅读更多相关信息

        TLDR(可能不准确且具有误导性,因此请阅读以上来源!): defer 属性告诉浏览器加载文件,但在 dom 准备好之前推迟执行,这与将 script 标签放在 body 标签底部时隐含的行为很接近,不同之处在于老方法你必须等待整个body标签被解析,直到你开始下载脚本标签。

        【讨论】:

          【解决方案6】:

          我在尝试做的时候遇到了这个问题(为简单起见,缩小了):

          <script type="text/javascript">
              var svg = document.querySelector('svg');
              console.log(svg);
          </script>
          

          &lt;body&gt;中的一个元素上:

          <svg id="svg" viewBox="0 0 120 120" width="500px" height="500px"></svg>
          

          一旦我添加了 jQuery 并将我的行移到 $(document).ready() 内,就很好了:

          <script type="text/javascript" src="jquery-1.12.4.min.js"></script>
          <script type="text/javascript">
              $(document).ready(function(){
                  var svg = document.querySelector('svg');
                  console.log(svg);
              });
          </script>
          

          【讨论】:

            猜你喜欢
            • 2020-09-22
            • 1970-01-01
            • 2014-10-21
            • 1970-01-01
            • 2020-10-29
            • 2013-01-26
            • 1970-01-01
            • 2021-07-15
            • 1970-01-01
            相关资源
            最近更新 更多