繁体   English   中英

将javascript和html分开以获取可读代码

[英]separating javascript and html for readable code

有时候我的javascript代码混合了html和css。 在这个stuation中,我的代码是不可读的。 你如何在javascript中分离javascript和html端?

例如:(使用javascript dojo工具包)

addLayer: function (layer, index) {                
var layerClass = layer.visible === true ? 'layer checked' : 'layer';
var html = '';
html += '<li class="' + layersClass + '">';
html += '<div class="cover"></div>';
html += '<span tabindex="0" class="info" title="MyTitle"></span>';
html += '<span tabindex="0" class="toggle box"></span>';
html += '<div class="clear"></div>';                    
html += '</li>';
var node = dom.byId('layersList');
if (node) {
    domConstruct.place(html, node, "first");
    HorizontalSlider({
        name: "slider",
        value: parseFloat(layer.opacity),
        minimum: 0,
        maximum: 1,
        showButtons: false,
        discreteValues: 20,
        intermediateChanges: true,
        style: "width:100px; display:inline-block; *display:inline; vertical-align:middle;",
        onChange: function (value) {
            layer.setOpacity(value);
        }
    }, "layerSlider" + index);

    if (!this.layerInfoShowClickHandler) {
        this.layerInfoShowClickHandler = on(query(".listMenu"), ".cBinfo:click, .cBinfo:keyup", this._onLayerInfoShowIconClicked);
    }
}                 
}

在这个阶段,我的代码是动态地添加html来查看。 将事件处理程序添加到创建的html代码中。 同时添加其他工具(HorizantalSlider)。 此工作流程彼此绑定。 此代码无法读取。 有没有办法用干净的代码来解决这个问题?

这个答案使用Dojo从JavaScript中分离HTML + CSS。

HTML模板

建议的方法是在单独的HTML文件中定义HTML模板。 例如:

<li class="{layersClass}">
    <div class="cover"></div>
    <span tabindex="0" class="info" title="MyTitle"></span>
    <span tabindex="0" class="toggle box"></span>
    <div class="clear"></div>
</li>

另请注意占位符替换layersClass


加载HTML模板

现在,要加载模板,请使用dojo/text插件。 使用此插件,您可以加载外部模板,例如使用:

require(["dojo/text!./myTemplate.html"], function(template) {
    // The "template" variable contains your HTML template
});

转换占位符

要替换{layersClass} ,可以使用dojo/_base/lang模块的replace()函数。 您的代码最终将如下所示:

require(["dojo/text!./myTemplate.html", "dojo/_base/lang"], function(myTemplate, lang) {
    var html = lang.replace(myTemplate, {
        layersClass: layersClass
    });
});

这将返回与您的html变量完全相同,但是从JavaScript代码中分离HTML。


单独的CSS

要从HorizontalSlider分离CSS样式,您可以定义一个id属性,并将CSS放在一个单独的CSS文件中。 您的HorizontalSlider将成为:

HorizontalSlider({
    name: "slider",
    value: parseFloat(layer.opacity),
    minimum: 0,
    maximum: 1,
    showButtons: false,
    discreteValues: 20,
    intermediateChanges: true,
    id: "mySlider",
    onChange: function (value) {
        layer.setOpacity(value);
    }
}, "layerSlider" + index);

现在您可以使用以下CSS:

#mySlider {
    width:100px;
    display:inline-block;
    *display:inline;
    vertical-align:middle;
}

您可以将html变量存储在不同的位置,例如,在名为template.js的文件中。 但是,这样做不能立即连接HTML字符串,因为您需要注入此layersClass变量。 这是一个可能的解决方法:

// template.js

var template = function () {
    return [
        '<li class="', this.layersClass, '">',
            '<div class="cover"></div>',
            '<span tabindex="0" class="info" title="MyTitle"></span>',
            '<span tabindex="0" class="toggle box"></span>',
            '<div class="clear"></div>',
        '</li>'
    ].join('');
};
// view.js

html = template.call({ 
    layersClass: layerClass 
});

有效且易于使用。 但是,如果要以字符串形式而不是函数形式使用模板,则需要模板解析器。 下面将给出与上面相同的结果(注意IE7 split()不支持正则表达式捕获):

function compile(tpl) {
    tpl = Array.prototype.join.call(tpl, '').split(/{{(.*?)}}/);
    return Function('return [' + tpl.map(function (v, i) {
        if (i % 2) return 'this["' + v + '"]';
        return v && '"' + v.replace(/"/g, '\\"') + '"';
    }).join(',') + '].join("");');
}

用法示例:

var template = '<b>{{text}}</b>';
var compiled = compile(template);
// compiled -> function () {
//     return ["<b>",this["text"],"</b>"].join("");
// }
var html1 = compiled.call({ text: 'Some text.' });
var html2 = compiled.call({ text: 'Bold this.' });
// html1 -> "<b>Some text.</b>"
// html2 -> "<b>Bold this.</b>"

现在,让我们看看如何使用此工具以一种干净的方式组织文件。

// product.data.js

product.data = [{ 
    name: 'Apple iPad mini', 
    preview: 'ipadmini.jpeg', 
    link: 'ipadmini.php',
    price: 280
}, { 
    name: 'Google Nexus 7',
    preview: 'nexus7.jpeg', 
    link: 'nexus7.php',
    price: 160
}, { 
    name: 'Amazon Kindle Fire',
    base64: 'kindlefire.jpeg', 
    link: 'kindlefire.php',
    price: 230
}];
// product.tpl.js

product.tpl = [
    '<div class="product">',
        '<img src="{{preview}}" alt="{{name}}" />',
        '<span>{{name}} - ${{price}}</span>',
        '<a href="details/{{link}}">details</a>',
    '</div>'
];
// product.view.js

var html = [];
var compiled = compile(product.tpl);
for (var i = 0, l = product.data.length; i < l; i++) {
    html.push(compiled.call(product.data[i]));
}
document.getElementById('products').innerHTML = html.join('');

演示: http//jsfiddle.net/wared/EzG3p/

更多详细信息: https//stackoverflow.com/a/20886377/1636522


这个compile函数可能不足以满足您的需求,我的意思是,您可能很快就需要一些功能更强大的功能,例如包含条件结构。 在这种情况下,您可以查看MustacheHandlebarsJohn Resig或Google “javascript模板引擎”

考虑使用模板来构建动态视图元素

例如:

http://handlebarsjs.com/

http://underscorejs.org/#template

一种方法是使用HTML (如果你不喜欢拆分你的逻辑,那就不那么酷了):

 <div style="display:none" id="jQ_addLayer">    
    <div class="cover"></div>
    <span tabindex="0" class="info" title="MyTitle"></span>
    <span tabindex="0" class="toggle box"></span>
    <div class="clear"></div>
  </div>

比jQuery用传递的变量创建LI并插入你的#jQ_addLayer内容:

var html = '<li class="'+layersClass+'">'+ $("#jQ_addLayer").html() +'</li>';

另一种方法是转义字符串换行符:

var html = '\
   <li class="' + layersClass + '">\
     <div class="cover"></div>\
     <span tabindex="0" class="info" title="MyTitle"></span>\
     <span tabindex="0" class="toggle box"></span>\
     <div class="clear"></div>\
   </li>'; //don't forget to escape possible textual single-quotes in your string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM