首先,除了一些教程之外,我对使用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,谢谢你给我指出正确的方向!