The site I am working on is using backbone and underscore in conjunction to render out page elements from data pulled out of a JSON file. Everything was working fine and dandy across all browsers, until I set IE to test in compatibility mode for IE 9. (I am not test in a native IE 9 enviortment - rather using the IE 10 developer window and setting browser mode for IE9 and Document Mode for IE9 standards).
The error is specifically:
SCRIPT1002: Syntax Error
with a pointer to the throw e; line of the try/catch call at the end of the _template function in underscore.js. (This is the section commented as If a variable is not specified, place data values in local scope) Now I can't imagine why the throw call would be generating the actual error, so I assume there is a problem somewhere up the line that is throwing the error in the try/catch, and IE is returning that instead of the line that actually made the error occur.
Full source for that section is:
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
I have spent a good amount of time in the IE developer window sifting through the code line by line with breakpoints, but at the point the error occurs, I have no idea what is actually being done by jquery / underscore, except that template is being called to render the elements. The only solution I found online so far was from people using reserved words as keys in their JSON, but that does not seem to be the case for me.
An individual object is the JSON file would look like:
{
"id": "1",
"title": "Project Title",
"client": "Client Name",
"scope": "Design and Producion",
"projectCode": "homeEnt",
"projectType": "Home Entertainment",
"description": "Blah blah blah",
"video" : "false",
"mainImg": "images/gallery-he/project.jpg",
"fullImg": "images/gallery-he/project-full.jpg"
}
The two types of templates used in the HTML are:
<script id="projectTemplate" type="text/template">
<div class="<%= projectCode %>-box" rel="<%= id %>">
<div class="gradient-strip <%= projectCode %>" ><%= projectType %></div>
<img src=<%= mainImg %> alt="<%= title &>" class="project-img">
</div>
</script>
<script id="projectModel" type="text/template">
<div class="model-frame" rel="<%= id %>" style="display:none">
<div class="model-gradient <%= projectCode %>"><%= projectType %></div>
<div class="close-button"></div>
<a class="model-left-arrow"></a>
<img class="fullArt" src="<%= fullImg %>" alt ="<%= title %>" />
<a class="model-right-arrow"></a>
<div class="model-text-block">
<p class="model-text"><span class="bolded"><%= title %> </span></p>
<p class="model-text"><span class="bolded">Client: </span> <%= client %></p>
<p class="model-text" style="padding-bottom:10px;"><%= scope %></p>
<p class="model-text"><%= description %></p>
</div>
</div>
</script>
Even with some selective commenting, I was not able to deduce which of these was the problem child, as commenting out one broke the other, and vice versa.
Last, the view code:
var ProjectModelView = Backbone.View.extend({
tagName: "div",
className: "model-wrap",
events: {
// events are here, removed to save space
},
initialize: function() {
this.template = _.template($(this.options.templ).html());
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
// added functions are here (removed to save space)
});
var ProjectView = Backbone.View.extend({
tagName: "div",
className: "project-wrap",
initialize: function () {
this.template = _.template($('#projectTemplate').html());
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
events: {
// events...
},
// added functions...
});
var ProjectModelListView = Backbone.View.extend({
el: '#modelList',
initialize: function() {
this.collection = masterProjectList;
this.render();
},
render: function() {
this.$el.html("");
this.collection.each(function(project) {
this.renderItem(project);
}, this);
},
renderItem: function(project) {
var isVideo = project.get('video');
if (isVideo == "true") {
var projectModelView = new ProjectModelView({ model: project, templ: '#videoProjectModel' });
this.$el.append(projectModelView.render().el);
} else {
var projectModelView = new ProjectModelView({ model: project, templ: '#projectModel'});
this.$el.append(projectModelView.render().el);
}
}
});
var ProjectListView = Backbone.View.extend({
el: '#projectList',
initialize: function() {
this.collection = masterProjectList;
this.render();
},
render: function() {
this.$el.html("");
this.collection.each(function(project) {
this.renderItem(project);
}, this);
},
renderItem: function(project) {
var projectView = new ProjectView({ model: project });
this.$el.append(projectView.render().el);
}
});
Sorry this is so much text, but I am at a complete loss as to what aspect is causing this to fail in IE 8 / 9, so I am unsure what specifically I need to be modifying. Any ideas what would be making underscore go crazy in just specific browser versions?
You can see the site here:
http://www.thecrpgroup.com/crpweb/promo-site/
Thanks.
Looks like there is a wrong closing bee string in <script id="projectTemplate"
<img src=<%= mainImg %> alt="<%= title &>"
^---- Supposed to be %
Also don't forget the quotes for src (IE does not like that as well)
If that is not intentional or a typo. Generally IE8/IE9 behaves real bad with such typos.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With