Backbone / View JQuery问题 - _.extend不是函数,无法读取未定义

时间:2015-09-03 05:59:06

标签: javascript jquery backbone.js

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

我得“_ .extend不是函数”“Uncaught TypeError:BerlinConnectView不是函数”“无法读取属性”扩展'of undefined “错误当我的页面随机呈现AT时(我什么都没改变,有一刻我得到一个错误,重新加载并在一分钟之后得到另一个错误)。

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

我的文件结构是这样的:

  

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>

2 个答案:

答案 0 :(得分:0)

所以这可能会发生,具体取决于您使用require加载脚本的方式。除非您定义require,否则dependencies将尽可能异步加载文件。

您编写的代码似乎在竞争条件下运行,因为在您的应用程序代码执行之前未加载您的供应商库。

您可以使用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',
        // ...
    // ...
});

答案 1 :(得分:0)

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

<强>的index.html

Unable to load foreign library (ZEROMQ).
Error opening shared library libzmq.dll: %1 is not a valid Win32 application.
      [Condition of type CFFI:LOAD-FOREIGN-LIBRARY-ERROR]

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

感谢@jiminikiz正确方向的观点!