Underscore.js模板在仅限于IE 8/9的浏览器中出现语法错误

3
我正在处理的网站使用backbone和underscore来结合渲染从JSON文件中提取的数据的页面元素。在所有浏览器上一切都运行良好,直到我将IE设置为在IE 9兼容模式下测试。(我没有在本机IE 9环境中进行测试 - 而是使用IE 10开发人员窗口并将浏览器模式设置为IE9,文档模式设置为IE9标准)。 错误具体如下:
SCRIPT1002: Syntax Error

这段代码是在underscore.js的_template函数的try/catch调用结尾处指向throw e;行的指针。(这部分被注释为:如果未指定变量,请将数据值放在本地范围内)现在我无法想象为什么throw调用会生成实际错误,因此我假设出现了问题,抛出了try/catch中抛出错误的那一行,而IE返回的是导致错误发生的实际行。

该部分的完整源代码如下:

// 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;
}

我在IE开发者窗口花了不少时间逐行查看代码并设置断点,但当错误发生时,我并不知道jquery/underscore实际执行了什么操作,除了调用模板来渲染元素。目前我在网上找到的唯一解决方案是使用保留字作为JSON键的人,但这似乎并不适用于我的情况。
JSON文件中的单个对象如下:
{ 
    "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"
}

HTML中使用的两种模板类型是:
<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>

即使进行了一些选择性注释,我仍然无法推断出哪一个是问题儿童,因为注释掉其中一个会破坏另一个,反之亦然。
最后,视图代码:
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);
    }
  });

抱歉,这是如此多的文本,但我完全不知道是哪个方面导致在IE 8/9中失败,所以我不确定我需要修改什么。有什么想法会让下划线在特定的浏览器版本中变得疯狂吗?
您可以在此处查看该网站:

http://www.thecrpgroup.com/crpweb/promo-site/

谢谢。

1个回答

3

看起来在<script id="projectTemplate"中有一个错误的闭合bee字符串

<img src=<%= mainImg %> alt="<%= title &>" 
                                       ^---- Supposed to be %

还有不要忘记src属性加上引号(IE也不喜欢这样)。

如果这不是故意的或者是一个打字错误,通常情况下,IE8/IE9对这样的打字错误表现得非常糟糕。


我的错误,我没有意识到underscore.js模板也是这样工作的。 - Jason Sperske
@JasonSperske.. 这就是下划线使用 bee 字符串来封装数据的方式... 它不是 ASP.NET.. 尽管它看起来与你在 ASP.NET 中想到的那个类似 :) - Sushanth --
男人。就是这样。加上IMG的引号并修复模板的结束标记就解决了。非常感谢。我相信明天我会觉得很有趣,因为问题归结为HTML中一个愚蠢的类型错误,而我却在JS代码中花了几个小时。 - DrHall
@DrHall.. 这种情况尤其发生在IE浏览器上。有第二个人帮忙看总是很有帮助的 ;) - Sushanth --

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接