主干/查看 JQuery 问题 - _.extend 不是一个函数,无法读取未定义的属性"扩展"



首先,除了一些教程之外,我对使用Backbone的知识非常有限,所以提前感谢任何提供任何帮助的人。我使用JQuery和Backbone来基本设置页面的响应性和隐藏的侧边栏导航。

我得到"_。扩展不是一个函数""未捕获的TypeError: BerlinConnectView不是一个函数""不能读取属性'extend'的未定义"错误时,我的页面随机呈现(我什么都不改变,有一刻我得到一个错误,重新加载,并得到另一个一分钟后)。

希望有人能看看我的代码,并提供一些帮助,因为我现在几天看相同的代码没有解决方案。

我的文件结构如下:

js


助手——helpers.js
供应商
——backbone.js
——jquery.js
——require.js
——underscore.js
视图
——BerlinConnectView.js
main.js

BerlinConnectView.js:

//BerlinConnectView.js
define([
  'vendor/jquery',
  'vendor/underscore',
  'vendor/backbone',
  'helpers/helpers'
], function($, _, Backbone, helpers) {
  return Backbone.View.extend({
    'el': 'body',
    'events': {
      'click .scroll a[href*=#]': 'scrollToAnchor',
      'click .slate.dimmed, .thelightbox, .sidebar-container li.internal, .nav-links ul li.internal': 'onLickLightboxLink',
      'click .lightbox .close, .lightbox-container .close-lightbox, .lightbox .lightbox-overlay, .dark-overlay': 'closeLightbox',
      'click .sidebar-control': 'toggleSidebar',
      'click .sidebar .close': 'closeSidebar',
      'mousedown button[data-track]': 'onClickAnylyticsLink',
    },
    'render': function() {
      var self = this;
      // Set high res images if user is on retina
      self.setRetinaInlineImages();
      // Check Scroll Position
      self.checkScrollPosition();
      // Check Scroll Position
      self.outsideLinks();
      // Check if mobile
      self.isMoblie();
      // Creates a sticky menu
      self.stickyMenu();
      //
      self.videoHider();
      // self.checkHash();
    },
    // checkHash:function() {
    //   var self = this;
    //   var hash = window.location.hash.replace('#','');
    //   if(hash.length === 0) return;
    //   self.openLightbox(hash);
    // },
    'videoHider': function() {
      var self = this;
      // setTimeout(function() {
      //   $('.video-hero .logo').addClass('fadeIn');
      // }, 12000);
      setTimeout(function() {
        $('.video-hero').addClass('fadeOut');
      }, 1000);
      $(".video-hero video").bind("ended", function() {
        $('.video-hero').addClass('backgroundAdded');
      });
    },
    'isMoblie':function() {
      var self = this;
      var ismobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent.toLowerCase());
      if (ismobileDevice)
      {
        $('*').css("background-attachment", "scroll")
        $('.mobile').removeClass("hidden")
        $('.desktop').addClass("hidden")
      }
    },
    'outsideLinks':function() {
      var self = this;
      $(document.links).filter(function() {
          return this.hostname != window.location.hostname;
      }).attr('target', '_blank');
    },
    'trackEvent': function (section, area, action) {
      return _gaq.push(['_trackEvent', section, area, action]);
    },
    'onClickAnylyticsLink':function (ev) {
      var self = this;
      var $target = $(ev.target);
      if (ev.target.tagName !== 'A') {
        $target = $target.closest('a');
      }
      var href = $target.attr('href');
      var parts = $target.attr('data-track').split(':');
      self.trackEvent(parts[0], parts[1], parts[2]);
    },
    'toggleSidebar': function () {
      var self = this;
      var $body = $('body');
      $body.toggleClass('active');
      // document.location.hash = '!';
    },
    'closeSidebar': function () {
      var self = this;
      var $body = $('body');
      $body.removeClass('active');
      // document.location.hash = '!';
    },
    'stickyMenu': function () {
      var self = this;
      var $header = $(".menu"),
      $clone = $header.before($header.clone().addClass("clone"));
      $(window).on("scroll", function() {
        var fromTop = $(window).scrollTop();
        var height = $('.hero, .sub-hero, .video-hero').height();
        $(".menu.clone").toggleClass("down", (fromTop > height));
      });
    },
    'onLickLightboxLink': function (ev) {
      var self = this;
      var $target = $(ev.target);
      if (!$target.hasClass('slate, thelightbox, sidebar-container li.internal, nav-links ul li ')) {
        $target = $target.closest('.slate, .thelightbox, .sidebar-container li.internal , .nav-links ul li');
      }
      var elementId = $target.attr('id');
      self.openLightbox(elementId);
    },
    openLightbox: function(id) {
      // document.location.hash = '!';
      $('.lightbox.' + id).removeClass('hidden');
      $('.dark-overlay').removeClass('hideme');
      $('.lightbox .lightbox-overlay').removeClass('hidden');
      $('body').css("overflow", "hidden");
      // window.location.hash = id;
    },
    'closeLightbox': function () {
      var self = this;
      var $lightbox = $('.lightbox');
      $lightbox.addClass('hide');
      $('.dark-overlay').addClass('hide');
      $('body').css("overflow", "auto");
      setTimeout(function() {
        $lightbox.addClass('hidden');
        $('.dark-overlay').addClass('hideme');
        $lightbox.removeClass('hide');
        $('.dark-overlay').removeClass('hide');
      }, 500);
      // document.location.hash = '!';
    },
    'setRetinaInlineImages': function () {
      var self = this;
      var $retinaImages = self.$('img.retina-image, img.col-image');
      if (window.devicePixelRatio > 1) {
        $retinaImages.each(function() {
          var src = $(this).attr('src');
          if (src) {
            src = src.replace(/(.)(jpg|png)($|?)/, '@2x.$2');
            $(this).attr('src', src);
          }
        });
      }
    },
    'scrollToAnchor': function(ev) {
      var self = this;
      var hash = $(ev.target).closest('a').attr('href');
      var $anchor = $(hash);
      if($anchor.length) {
        ev.preventDefault();
        self.$el.animate({scrollTop:$anchor.offset().top}, 500, function () {
          window.location.hash = hash;
        });
      }
    },
    'checkScrollPosition': function() {
      var self = this;
      function checkPosition () {
        var position = $(window).scrollTop();
        var windowHeight = $(window).height();
        var documentHeight = $(document).height();
        var height = $('.hero').height();
        var footerHeight = $('footer').height();
        Backbone.Events.trigger('scroll', position);
        if (position + windowHeight == documentHeight) {
          $(".menu.clone").toggleClass("down");
          $("body").removeClass('active');
        }
      }
      throttledPositionCheck = _.throttle(checkPosition, 250);
      $(window).on('scroll', throttledPositionCheck);
    }
  });
});

Main.js

//main.js
 require([
'vendor/jquery',
'vendor/underscore',
'vendor/backbone',
'views/BerlinConnectView'
], function($, _, Backbone, BerlinConnectView) {
var berlinConnectView = new BerlinConnectView();
berlinConnectView.render();
});

index . html

<head>
<!--Header Content
...................
...................
...................
-->
  <!-- Scripts -->
<script type="text/javascript" src="/js/vendor/require.js"></script>
  <script type="text/javascript">
    window.require = requirejs.config({
      'baseUrl': '/js',
      'context': 'bc'
    });
</script>
<script type="text/javascript" src="/js/main.js"></script>

  <!-- Google Analytics
  <script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-82811-13']);
    _gaq.push(['_setDomainName', 'myberlinconnect.de']);
    _gaq.push(['_setAllowLinker', true]);
    _gaq.push(['_trackPageview']);
    (function() {
      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();
  </script>
  -->
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="bc" data-requiremodule="vendor/jquery" src="/js/vendor/jquery.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="bc" data-requiremodule="vendor/underscore" src="/js/vendor/underscore.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="bc" data-requiremodule="vendor/backbone" src="/js/vendor/backbone.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="bc" data-requiremodule="views/BerlinConnectView" src="/js/views/BerlinConnectView.js"></script>
<script type="text/javascript" charset="utf-8" async="" data-requirecontext="bc" data-requiremodule="helpers/helpers" src="/js/helpers/helpers.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.gstatic.com/maps-api-v3/api/js/22/2/common.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.gstatic.com/maps-api-v3/api/js/22/2/util.js"></script>
<script type="text/javascript" charset="UTF-8" src="https://maps.gstatic.com/maps-api-v3/api/js/22/2/stats.js"></script>

</head>

这取决于您如何使用require来加载脚本。require将尽可能异步加载文件,除非您定义了dependencies

你写的代码似乎遇到了竞争条件,因为你的供应商库在你的应用程序代码执行之前没有被加载。

您可以使用use require.config来定义dependencies并同步加载供应商库。

在你的main.js:

// main.js
require.config({
    // shim allows us to configure dependencies for scripts 
    // that do not call define() to register a module 
    // e.g. vendor libs, like jQuery, underscore, Backbone, etc...
    shim: {
        backbone: {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        }    
    },
    paths: {
        // vendor libs
        jquery:     'vendor/jquery',
        underscore: 'vendor/underscore',
        backbone:   'vendor/backbone'
    }
});
require([
    'backbone',
    'views/BerlinConnectView'
], function( Backbone, BerlinConnectView ) {
    // at this point, $, _, and Backbone are already loaded and 
    // available within the `window` object
    var berlinConnectView = new BerlinConnectView();
    berlinConnectView.render();
});

BerlinConnectView.js:

define([
    'helpers/helpers',
], function(helpers) {
    // at this point window.Backbone should exist
    // so you should be able to refer to it globally
    return Backbone.View.extend({
        'el': 'body',
        // ...
    // ...
});

在@jiminikiz的帮助下,我意识到我在HTML和main.js中都调用了依赖项。我删除了HTML调用,所以我的脚本看起来是这样的:

index . html

<!-- Scripts -->
<script type="text/javascript" src="/js/vendor/require.js"></script>
  <script type="text/javascript">
    window.require = requirejs.config({
      'baseUrl': '/js',
      'context': 'bc'
    });
  </script>
  <script type="text/javascript" src="/js/main.js"></script>

删除对其他依赖项的调用后,代码正确执行,没有错误。

@jiminikiz,谢谢你给我指出正确的方向!

最新更新