Vue项目 - 一个自定义js脚本出现的Uncaught TypeError: Cannot read properties of null (reading 'offsetWidth')错误
P粉447785031
P粉447785031 2023-12-13 11:48:24
0
1
616

所以我将自定义 html 模板转换为 vuejs 项目。 我已经导入了主页中要使用的所有 css 和 js 文件。 CSS 文件加载正常。 对于 JS 文件,主题附带了一些自定义 js 脚本以及常用的库,如 Three.js 等。 我将所有这些导入到脚本标记中的 HomeComponent 下方。 但我遇到了这个错误:

"Uncaught TypeError: Cannot read properties of null (reading 'offsetWidth')
    at eval (demo3.js?dad6:2:20)
    at ./src/assets/assets/js/demo3.js (app.js:92:1)
    at __webpack_require__ (app.js:1124:33)
    at fn (app.js:1357:21)
    at eval (index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js:26:85)
    at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:30:1)
    at __webpack_require__ (app.js:1124:33)
    at fn (app.js:1357:21)
    at eval (HomeComponent.vue?vue&type=script&lang=js:5:216)
    at ./src/components/HomeComponent.vue?vue&type=script&lang=js (app.js:296:1)"

下面是我的 App.vue 代码:

<template>
  <router-view />
</template>
<script>
export default {
  name: "App",
  components: {},
};
</script>

下面是我的 homecomponent.vue 代码(部分 - 一些代码隐藏在模板内部):

<template>
  <header class="offcanvas-menu">
    <input type="checkbox" id="toogle-menu" />

    <label for="toogle-menu" class="toogle-open"><span></span></label>

    <nav>
      <div>
        <label for="toogle-menu" class="toogle-close">
          <span></span>
        </label>
      </div>
      <ul>
        <li><a href="#section1">Section </a></li>
        <li><a href="#section2">Section </a></li>
        <li><a href="#section3">Section </a></li>
        <li><a href="#section4">Section </a></li>
        <li><a href="#section5">Section </a></li>
      </ul>
    </nav>
  </header>
  <main>
    <div class="content">
      <canvas class="scene scene--full" id="scene"></canvas>
      <div class="content__inner">
        <h2 class="content__title">مؤشر المعلوماتية</h2>
        <div class="content-button mt-2">
          <button
            type="button"
            class="btn btn-relief-primary btn-large menu-trigger display-5"
          >
            <i data-feather="menu"></i> القائمة
          </button>
        </div>
      </div>
    </div>

    <nav class="grim">
      <div class="grim__item">
        <div class="grim__item-bg grim__item-bg--5"></div>
      </div>
      <div class="grim__item">
        <div class="grim__item-bg grim__item-bg--5"></div>
      </div>
      <div class="grim__item">
        <div class="grim__item-bg grim__item-bg--5"></div>
        <div class="grim__item-content">
          <div class="grim__item-inner"></div>
        </div>
      </div>
  ..
   
    
      <div class="grim__item">
        <div class="grim__item-bg grim__item-bg--9"></div>
        <div class="grim__item-img grim__item-img--4"></div>
        <a href="dashboard-region.html" class="grim__link grim__item-content">
          <div class="grim__item-inner">
            <h3 class="grim__item-title">test</h3>
            <span class="grim__item-desc">test</span>
          </div>
        </a>
        <div class="grim__item-bg grim__item-bg-cover grim__item-bg--9"></div>
      </div>
      <div class="grim__item">
        <div class="grim__item-bg grim__item-bg--10"></div>
        <div class="grim__item-img grim__item-img--5" style=""></div>
        <a href="wizard.html" class="grim__link grim__item-content">
          <div class="grim__item-inner">
            <h3 class="grim__item-title">test</h3>
            <span class="grim__item-desc"
              >test</span
            >
          </div>
        </a>
        <div class="grim__item-bg grim__item-bg-cover grim__item-bg--10"></div>
      </div>
    </nav>
  </main>
  <!-- home -->
</template>
<style>
@import url("https://fonts.googleapis.com/css?family=Barlow:400,500,700|Poppins:600");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500;1,600");
</style>
<script>
//All css files
import "../assets/assets/css/base.css";

import "../assets/app-assets/css-rtl/bootstrap.css";
import "../assets/app-assets/css-rtl/bootstrap-extended.css";
import "../assets/app-assets/css-rtl/colors.css";
import "../assets/app-assets/css-rtl/themes/dark-layout.css";
import "../assets/assets/css/menu.css";

import "../assets/app-assets/css-rtl/custom-rtl.css";
import "../assets/assets/css/style-rtl.css";

export default {
  name: "HomeComponent",
};

//All JS files
import "../assets/assets/js/demo.js";
import "../assets/assets/js/three.min.js";
import "../assets/assets/js/perlin.js";
import "../assets/assets/js/TweenMax.min.js";
import "../assets/assets/js/demo3.js";
import "../assets/assets/js/grid.js";
import "../assets/assets/js/imagesloaded.pkgd.min.js";
import "../assets/assets/js/anime.min.js";
import "../assets/assets/js/menu2.js";
</script>

问题出在 demo3.js 文件上。

Demo3.js

var canvas = document.querySelector("#scene");
var width = canvas.offsetWidth,
  height = canvas.offsetHeight;

var renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  antialias: true,
});
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);
renderer.setSize(width, height);
renderer.setClearColor(0x161d31);

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(100, width / height, 0.1, 10000);
camera.position.set(120, 0, 300);

var light = new THREE.HemisphereLight(0xffffff, 0x0c056d, 0.6);
scene.add(light);

var light = new THREE.DirectionalLight(0x590d82, 0.5);
light.position.set(100, 300, 400);
scene.add(light);
var light2 = light.clone();
light2.position.set(-100, 300, 400);
scene.add(light2);

var geometry = new THREE.IcosahedronGeometry(120, 4);
for (var i = 0; i < geometry.vertices.length; i++) {
  var vector = geometry.vertices[i];
  vector._o = vector.clone();
}
var material = new THREE.MeshPhongMaterial({
  emissive: 0x23f660,
  emissiveIntensity: 0.4,
  shininess: 0,
});
var shape = new THREE.Mesh(geometry, material);
scene.add(shape);

function updateVertices(a) {
  for (var i = 0; i < geometry.vertices.length; i++) {
    var vector = geometry.vertices[i];
    vector.copy(vector._o);
    var perlin = noise.simplex3(
      vector.x * 0.006 + a * 0.0002,
      vector.y * 0.006 + a * 0.0003,
      vector.z * 0.006
    );
    var ratio = perlin * 0.4 * (mouse.y + 0.3) + 0.9;
    vector.multiplyScalar(ratio);
  }
  geometry.verticesNeedUpdate = true;
}

function render(a) {
  requestAnimationFrame(render);
  updateVertices(a);
  renderer.render(scene, camera);
}

function onResize() {
  canvas.style.width = "";
  canvas.style.height = "";
  width = canvas.offsetWidth;
  height = canvas.offsetHeight;
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
}

var mouse = new THREE.Vector2(0.8, 0.5);
function onMouseMove(e) {
  TweenMax.to(mouse, 0.8, {
    y: e.clientY / height,
    x: e.clientX / width,
    ease: Power1.easeOut,
  });
}

requestAnimationFrame(render);
window.addEventList ener("mousemove", onMouseMove);
var resizeTm;
window.addEventList ener("resize", function () {
  resizeTm = clearTimeout(resizeTm);
  resizeTm = setTimeout(onResize, 200);
});

所以,我的应用程序根本无法加载。现在我不知道如何解决这个问题。这是我第一次将 html 模板转换为 vuejs。我不知道会发生什么。 文件结构截图 (https://i.stack.imgur.com/dKzTb.png)

console.log 中错误详细信息的屏幕截图 (https://i.stack.imgur.com/9Rzap.png)

P粉447785031
P粉447785031

全部回复(1)
P粉920485285

您将在应用呈现 DOM 之前导入 demo3.js 文件(并执行它)。因此元素 #scene 尚不存在,导致为 null

几种解决方案:

  1. 您可以在 mounted 挂钩后动态导入 demo3.js 文件:
mounted() {
  import('../assets/assets/js/demo3.js') // dynamic import
}
  1. demo3.js 代码包装在函数内并将其导出。
// demo3.js

export function renderScene() {
  var canvas = document.querySelector("#scene");
  var width = canvas.offsetWidth,
    height = canvas.offsetHeight;
  // [...]
}
import { renderScene } from '../assets/assets/js/demo3.js'

export default {
  mounted() {
    renderScene()
  }
}
  1. 您将 demo3.js 代码移至 vue 组件,并使用模板引用。
mounted() {
  const scene = this.$refs.scene
  if (scene) {
    const width = canvas.offsetWidth,
      height = canvas.offsetHeight;

    const renderer = new THREE.WebGLRenderer({
      canvas: canvas,
      antialias: true,
    });
    // [...]
  }
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板