有时我的javascript代码与html和css混合。在这个stuation中,我的代码是不可读的。你如何在javascript中分离javascript和html?
例如:(使用javascript dojo toolkit)
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)。 此工作流程彼此绑定。此代码无法读取。有没有办法用干净的代码解决这个问题?
答案 0 :(得分:2)
这个答案使用Dojo从JavaScript中分割HTML + CSS。
推荐的方法是在单独的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
。
现在,要加载模板,请使用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。
要从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;
}
答案 1 :(得分:1)
您可以将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
函数可能不足以满足您的需求,我的意思是,您可能很快就需要一些功能更强大的功能,例如包含条件结构。在这种情况下,您可以查看Mustache,Handlebars,John Resig或Google "javascript templating engine"。
答案 2 :(得分:0)
答案 3 :(得分:0)
一种方法是使用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