首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >由于Navbar,Nuxt.js抛出在“Node”上执行“appendChild”失败

由于Navbar,Nuxt.js抛出在“Node”上执行“appendChild”失败
EN

Stack Overflow用户
提问于 2022-11-25 14:27:55
回答 1查看 38关注 0票数 0

我有一个Nuxtjs网站托管在S3桶,它有多个路由/页面。我创建的这条特殊的新路径是抛出“未能在‘node’上执行'appendChild‘:此节点类型不支持此方法.”(请查看下面的SS )。

这种情况不会发生在本地机器上,也不会抛出任何错误。显然,当我部署到prod时,这个应用程序正在抛出SS下面的错误,但是不能调试它,因为代码在构建过程中被缩小和丑陋了。

奇怪的是,当我通过单击<NuxtLink>访问这个特定的路径时,它工作得很好,但是如果我访问的路线很笨拙,或者我单击<NuxtLink>并到达那里并重新加载页面,那么这个问题才会出现。

您可以通过以下步骤来再现这个过程:

  1. 访问https://stackinvest.in
  2. 从导航栏点击“堆栈质数”,这将导致https://stackinvest.in/prime-mutual-funds
  3. 一旦你在堆栈的黄金页面,重新加载页面。你会看到错误的。

如果直接访问https://stackinvest.in/prime-mutual-funds路由,也可以看到此错误。

问题是,也有其他路线,你可以看到在Navbar主页上。如果我遵循以上步骤的话,它们都能正常工作。(https://www.stackinvest.in/)

我有一个默认的布局文件(由Nuxt本身创建) layouts/default.vue。代码如下:

代码语言:javascript
运行
复制
<template>
  <div ref="layout">
    <app-navbar :isMobile="isMobile" @getstack="showModal = true"/>
    <nuxt />
    <app-download v-if="showModal" :is-mobile="isMobile" @close="showModal=false"></app-download>
  </div>
</template>
<script>
import Navbar from '../components/Navbar';
import Download from '../components/Download';

export default {
  name: 'Navbar',
  components: {
    appNavbar: Navbar,
    appDownload: Download
  },
  data() {
    return {
      showModal: false,
      size: Number
    };
  },
  computed: {
    isMobile() {
      return this.size < 768;
    }
  },
  mounted() {
    this.size = this.$refs.layout.clientWidth;
  }
};
</script>

代码components/Navbar.vue。它不包含.removeEventListener()的任何代码。我确实尝试过在<client-only></client-only>标签周围添加<app-navbar>包装标签。什么都没用!

代码语言:javascript
运行
复制
<template>
  <nav class="nav-bar">
    <div class="d-flex justify-content-center px-0 px-sm-128">
      <div v-if="!isMobile" class="nav-bar-wrapper py-sm-4">
        <div class="brand-logo">
          <NuxtLink to="/">
            <img alt="Stack Finance logo" data-not-lazy height="35px"
                 src="https://webstatic.stackfinance.co/website/Group 73740.svg"
            >
          </NuxtLink>
        </div>
        <div class="d-flex justify-content-center">
          <div class="nav-links w-100 mr-sm-4">
            <div class="nav-links-item">
              <NuxtLink class="fo-link" to="/prime-mutual-funds">
                stack prime
                <div class="designer-line"></div>
              </NuxtLink>
            </div>
            <div class="nav-links-item">
              <NuxtLink class="fo-link gt-nav-faq" to="/faq">
                faq
                <div class="designer-line"></div>
              </NuxtLink>
            </div>
            <div class="nav-links-item">
              <NuxtLink class="fo-link gt-nav-blog" to="/blogs">
                blog
                <div class="designer-line"></div>
              </NuxtLink>
            </div>
          </div>
          <button id="nav-cta" ref="navCta" class="app-btn--sm" @click="focusSection">download stack</button>
        </div>
      </div>
      <div v-else class="nav-bar-wrapper--mob p-3">
        <div class="brand-logo">
          <NuxtLink to="/">
            <img alt="Stack Finance logo" data-not-lazy height="22px"
                 src="https://webstatic.stackfinance.co/website/Group 73740.svg"
            >
          </NuxtLink>
        </div>
        <div class="nav-links--collapsed">
          <div class="menu-icon">
            <input id="toggle" type="checkbox" @change="toggleMenu">
            <label for="toggle"></label>
          </div>
        </div>
        <div v-if="showMenu" class="menu-container">
          <div class="nav-links-item">
            <NuxtLink class="fo-link" to="/prime-mutual-funds">stack prime</NuxtLink>
          </div>
          <div class="nav-links-item gt-nav-faq">
            <NuxtLink class="fo-link" to="/faq">faq</NuxtLink>
          </div>
          <div class="nav-links-item">
            <NuxtLink class="fo-link gt-nav-blog" to="/blogs">blog</NuxtLink>
          </div>
        </div>
      </div>
    </div>
  </nav>
</template>

<script>
export default {
  name: 'Navbar',
  props: {
    isMobile: Boolean
  },
  data() {
    return {
      showMenu: false
    };
  },
  methods: {
    focusSection() {
      this.$emit('getstack');
    },
    toggleMenu() {
      this.showMenu = !this.showMenu;
    }
  }
};
</script>

<style lang="scss">
...
</style>

package.json

代码语言:javascript
运行
复制
{
  "name": "stack-web",
  "version": "4.0.0",
  "description": "",
  "author": "XYZ,
  "private": true,
  "scripts": {
    "dev:staging": "gulp set --env=staging && nuxt",
    "dev:prod": "gulp set --env=prod && nuxt",
    "build:staging": "gulp set --env=staging && nuxt build",
    "build:prod": "gulp set --env=prod && nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore ."
  },
  "dependencies": {
    "@nuxtjs/axios": "^5.9.5",
    "@nuxtjs/dayjs": "^1.4.0",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/gtm": "^2.4.0",
    "@nuxtjs/robots": "^2.5.0",
    "@nuxtjs/sitemap": "^2.4.0",
    "@tryghost/content-api": "^1.11.0",
    "bootstrap-vue": "^2.2.2",
    "glob-all": "^3.1.0",
    "nuxt": "^2.0.0",
    "nuxt-helmet": "^1.2.3",
    "nuxt-lazy-load": "^1.2.9",
    "purgecss-webpack-plugin": "^2.0.5",
    "tinyurl": "^1.1.7",
    "vue": "^2.7.14",
    "vue-gtag": "^1.16.1",
    "vue-loader": "^15.10.0",
    "vue-slick-carousel": "^1.0.6",
    "vue-social-sharing": "^3.0.9",
    "vuelidate": "^0.7.7"
  },
  "devDependencies": {
    "@nuxt/types": "^2.15.7",
    "@nuxtjs/eslint-config": "^1.0.1",
    "@nuxtjs/eslint-module": "^1.0.0",
    "@nuxtjs/stylelint-module": "^3.1.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "gulp": "^4.0.2",
    "gulp-clean": "^0.4.0",
    "gulp-rename": "^2.0.0",
    "nuxt-compress": "^5.0.0",
    "sass": "^1.56.1",
    "sass-loader": "^10.1.1",
    "stylelint": "^10.1.0",
    "yargs": "^15.1.0"
  }
}

nuxt.config.js

代码语言:javascript
运行
复制
/* eslint-disable dot-notation */
// import path from 'path';
//
// import PurgecssPlugin from 'purgecss-webpack-plugin';
// import glob from 'glob-all';
// import shrinkRay from 'shrink-ray-current';
require('dotenv').config();

const keywords = `keywords`;

export default {
  mode: 'universal',
  server: {
    port: process.env.PORT || 5100,
    host: '0.0.0.0' // default: localhost
  },
  // render: {
  //   compressor: shrinkRay()
  // },
  router: {
    scrollBehavior() {
      let s;
      if (process.client) {
        s = { x: 0, y: 0 };
      }
      return s;
    }
  },
  /*
   ** Headers of the page
   */
  head: {
    ...
  },
  /*
   ** Customize the progress-bar color
   */
  loading: {
    color: '#fff'
  },
  /*
   ** Global CSS
   */
  css: [
    '@/assets/scss/app.scss'
  ],
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [
    { src: '~/plugins/Vuelidate' },
    { src: '~/plugins/hotjar', mode: 'client' },
    { src: '~/plugins/gtag', mode: 'client' },
    { src: '~/utils', mode: 'client' },
    { src: '~/plugins/directives.js' }
  ],
  /*
   ** Nuxt.js dev-modules
   */
  buildModules: [
    'nuxt-compress'
    // // Doc: https://github.com/nuxt-community/eslint-module
    // '@nuxtjs/eslint-module',
    // // Doc: https://github.com/nuxt-community/stylelint-module
    // '@nuxtjs/stylelint-module'
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    'bootstrap-vue/nuxt',
    '@nuxtjs/axios',
    '@nuxtjs/dotenv',
    '@nuxtjs/gtm',
    'nuxt-lazy-load',
    'nuxt-helmet',
    '@nuxtjs/robots',
    '@nuxtjs/sitemap',
    'vue-social-sharing/nuxt',
    '@nuxtjs/dayjs'
  ],
  robots: {
    ...
  },
  sitemap: {
    ...
  },
  gtm: {
    id: '<KEY>',
    pageTracking: true,
    pageViewEventName: 'nuxtRoute'
  },
  dayjs: {
    locales: ['en'],
    defaultLocale: 'en',
    plugins: [
      'utc' // import 'dayjs/plugin/utc'
    ]
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/i,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },
  bootstrapVue: {
    bootstrapCSS: false,
    bootstrapVueCSS: false
  },
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extractCSS: true,
    extend(config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.devtool = 'source-map';
        config.plugins.push(
          // new PurgecssPlugin({
          //   paths: glob.sync([
          //     path.join(__dirname, './pages/**/*.vue'),
          //     path.join(__dirname, './layouts/**/*.vue'),
          //     path.join(__dirname, './components/**/*.vue')
          //   ]),
          //   whitelist: ['html', 'body']
          // })
        );
      }
    }
  }
};

prime-mutual-funds.vue代码

代码语言:javascript
运行
复制
<template>
  <main ref="page" class="prime-main">
    <section class="hero">
      ...
    </section>

    <section class="risk-analysis">
      <div class="row">
        <div v-if="!isMobile" class="col-sm">
          ...
        </div>
        <div class="col-sm d-flex align-items-center mb-4 mb-sm-0">
          <div>
           
            <a v-if="isMobile" class="text-color text-decoration-done fw-600" :href="getOS() === 'android' ? 'URL1': 'url2'">
              
            </a>
            <a v-else class="text-color text-decoration-done fw-600" @click="showModal = true" href="javascript:void(0)">
              ...
            </a>
          </div>
        </div>
        <div v-if="isMobile" class="col-sm">
         ...
        </div>
      </div>
    </section>

    <section class="prime-detail">
      <div class="prime-detail-header">
        <h2 class="section-heading">Lorem Lorem</h2>
        <div class="d-flex mt-3 mt-sm-4">
          <a href="#options" class="prime-detail-tab" @click="activeTabIndex = 0" :class="{'active': activeTabIndex === 0}">investment options</a>
          <a href="#automate" class="prime-detail-tab" @click="activeTabIndex = 1" :class="{'active': activeTabIndex === 1}">automated investing</a>
          <a href="#track" class="prime-detail-tab" @click="activeTabIndex = 2" :class="{'active': activeTabIndex === 2}">actionable insights from experts</a>
        </div>
      </div>

      <section id="options" class="p-4" v-if="isMobile">
        ...
      </section>
      <section v-else class="scroller pb-sm-128">
        <div class="scroller-left">
          <div id="options" class="scrollable-element">
            <div id="1" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
             ...
            </div>
          </div>
          <div class="scrollable-element">
            <div id="2" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
             ...
            </div>
          </div>
          <div id="automate" class="scrollable-element">
            <div id="3" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
              ...
            </div>
          </div>
          <div class="scrollable-element">
            <div id="4" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
              ...
            </div>
          </div>
          <div class="scrollable-element">
            <div id="5" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
              ...
            </div>
          </div>
          <div id="track" class="scrollable-element">
            <div id="6" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
              ...
            </div>
          </div>
          <div class="scrollable-element">
            <div id="7" class="mxw-600" v-intersection="{threshold: .7, cb: updateRightContainer}">
              ...
            </div>
          </div>
        </div>
        <div class="scroller-right">
          <div class="sticky-content">
            <div class="sticky-content-box" v-if="activateText">
              <span class="sticky-content-tag" :style="{backgroundColor: contentIndex[activeContentIndex].bgc}">{{ contentIndex[activeContentIndex].tag }}</span>
              <h3 class="sticky-content-title mt-4">
                {{ contentIndex[activeContentIndex].title }}
              </h3>
            </div>
            <img v-else height="520px" ref="info" alt="info-img" src="https://webstatic.stackfinance.co/website/goals.webp"/>
          </div>
        </div>
      </section>
    </section>

    <section class="rewards">
      <h3 v-if="isMobile" class="rewards-heading">good financial habits <br> deserve <span class="text-white">great</span> rewards</h3>
      <h3 v-else class="rewards-heading">good financial habits deserve <br> <span class="text-white">great</span> rewards</h3>
      <h5 class="rewards-subheading">choose a free US stock with every investment.</h5>
      <a :href="getOS() === 'android' ? '<url1>': '<url1>'"
         v-if="isMobile" class="app-btn--sm d-block bgi-none bg-white text-color mx-auto my-4" style="width: 190px;">
        download stack
      </a>
      <button v-else class="app-btn--white mt-sm-4" @click="showModal = true">download stack</button>
    </section>

    <app-grow-wealth :is-mobile="isMobile" @download="showModal = true"></app-grow-wealth>
    <app-footer :is-mobile="isMobile"></app-footer>

    <div v-if="isMobile" class="store-container py-2 px-4 bg-white position-fixed">
      <a href="https://stack.app.link/3yAcChs5emb" rel="noopener">
        <img height="40px" src="https://webstatic.stackfinance.co/website/playstore.png" alt="playstore">
      </a>
      <a href="https://stack.app.link/10JkMU6Xemb" rel="noopener">
        <img class="float-right" height="40px" src="https://webstatic.stackfinance.co/website/appstore.png" alt="appstore">
      </a>
    </div>

    <div v-if="showFaq" class="pop-box">
      <app-faq-section :squeeze="true"></app-faq-section>
    </div>
    <button id="popover-button-sync" class="floating-help" @click="showFaq = !showFaq">
      <img height="40px" src="https://webstatic.stackfinance.co/website/Chat 4_2x.png" alt="messenger">
    </button>
    <app-download v-if="showModal" :is-mobile="isMobile" @close="showModal=false"></app-download>
  </main>
</template>

<script>
import Footer from '../components/Footer';
import FaqSection from '../components/Faq-Section';
import Download from '../components/Download';
import { fetchOS } from '../utils';
import GrowWealth from '../components/GrowWealth';

export default {
  name: 'PrimeMutualFunds',
  components: {
    appFooter: Footer,
    appFaqSection: FaqSection,
    appDownload: Download,
    appGrowWealth: GrowWealth
  },
  data() {
    return {
      size: Number,
      showModal: false,
      showFaq: false,
      activateText: false,
      activeTabIndex: 0,
      imgIndex: {
        1: 'URL',
        2: 'URL',
        6: 'URL',
        7: 'URL'
      },
      contentIndex: {
        3: {
          tag: '...',
          bgc: '#f9f2ea',
          title: '...'
        },
        4: {
          tag: '...',
          bgc: '#e1f4f0',
          title: '...'
        },
        5: {
          tag: 'investment reminder',
          bgc: '#ccebff',
          title: '...'
        }
      },
      activeContentIndex: 3
    };
  },
  computed: {
    isMobile() {
      return this.size < 768;
    }
  },
  mounted() {
    this.size = this.$refs.page.clientWidth;
  },
  methods: {
    getOS: () => fetchOS(),
    updateRightContainer({ isIntersecting, target }) {
      if (isIntersecting) {
        const x = target.getAttribute('id');
        this.activeTabIndex = 0;
        const ids = [3, 4, 5];
        if (ids.includes(+x)) {
          this.activateText = true;
          this.activeContentIndex = x;
          this.activeTabIndex = 1;
          return;
        }

        if ([6, 7].includes(+x)) {
          this.activeTabIndex = 2;
        }

        this.activateText = false;
        if (this.$refs.info) {
          this.$refs.info.setAttribute('src', this.imgIndex[x]);
        }
      }
    }
  }
};
</script>

direction.js

代码语言:javascript
运行
复制
Vue.directive('intersection', {
  bind(el, binding) {
    const threshold = binding.value.threshold || 0;
    const defaultCb = () => {
      console.log('No callback passed');
    };
    const cb = binding.value.cb || defaultCb;

    if (isNaN(threshold)) {
      return;
    }
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((elem) => {
        cb(elem);
      });
    }, { threshold });
    observer.observe(el);
  }
});

Vue.directive('scroll', {
  inserted(el, binding) {
    const f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f);
      }
    };
    window.addEventListener('scroll', f);
  }
});

如果我注释掉了导航栏并进行了部署,那么这个URL -https://stackinvest.in/prime-mutual-funds的重新加载工作正常,没有任何问题。

EN

回答 1

Stack Overflow用户

发布于 2022-11-28 04:31:30

交叉口观测器windows只是客户端的代码(不能在Node.js上下文中使用)。

您不能像现在这样使用它们,因为它们现在都运行在客户端和服务器端。

如我在第一个评论中所建议的,请参考这个答案来解决这个问题(主要是在客户端运行您的代码)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74574249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档