以下代码运行正常,但我想让它更好:
function prodNameTrim(selector){
var el = document.getElementsByClassName(selector);
var len = el.length;
for(i = 0; i<len; i++){
aObj = el[i].getElementsByTagName('a');
txtNode = aObj[0].childNodes[0].nodeValue;
if(txtNode.length > 26){
txtNode = txtNode.substring(0, 27) + ' ...';
}
aObj[0].childNodes[0].nodeValue = txtNode;
}
}
我不喜欢的是我首先在条件之前建立txtNode:
txtNode = aObj[0].childNodes[0].nodeValue;
在我通过条件处理变量以截断带有省略号的字符串后,我执行以下操作来替换DOM中的文本:
aObj[0].childNodes[0].nodeValue = txtNode;
我不得不相信有更好的方法可以做到这一点,但我不确定那是什么,我觉得我好像打破了DRY规则。
答案 0 :(得分:2)
如果您只是想避免在任何地方重复aObj[0].childNodes[0]
部分,可以使用txtNode
变量来引用节点本身,而不是它的值:
function prodNameTrim(selector){
var el = document.getElementsByClassName(selector);
var len = el.length;
var txtNode; // declare txtNode with var
for(var i = 0; i<len; i++){
txtNode = el[i].getElementsByTagName('a')[0].childNodes[0];
if(txtNode.nodeValue.length > 26){
txtNode.nodeValue = txtNode.nodeValue.substring(0, 27) + ' ...';
}
}
}
你会发现你到处都在重复txtNode.nodeValue
,但最好还是每次都要包含aObj[0].childNodes[0]
。并且不需要在if
语句之后将子字符串版本写回节点的行,因为该更新现在直接在if
内发生。
另请注意,您应该使用var
声明所有变量,否则它们将成为全局变量。 (我上面显示的方式实际上根本不需要aObj
变量。)
答案 1 :(得分:2)
我会建议:
function prodNameTrim(selector){
var el = document.getElementsByClassName(selector),
len = el.length, node;
for(var i = 0; i < len; i++) {
node = el[i].getElementsByTagName('a')[0].firstChild;
if(node.nodeValue.length > 26){
node.nodeValue = node.nodeValue.substring(0, 27) + ' ...';
}
}
}
的变化:
i
,aObj
或txtNode
)aObj
中间件if
语句中对nodeValue进行赋值,因为这是唯一更改的位置.firstChild
代替.childNodes[0]
我想知道这是否可行(可能需要IE9或更高版本,并且希望确定HTML以确定并运行一些浏览器测试),但一般的想法是使用querySelectorAll()
并结合两个搜索进入一个更复杂的CSS选择器:
function prodNameTrim(rootClass) {
var items = document.querySelectorAll("." + rootClass + " a:first-of-type"), node;
for (var i = 0; i < items.length; i++) {
node = items[i].firstChild;
if (node.nodeValue.length > 26) {
node.nodeValue = node.nodeValue.substring(0, 27) + ' ...';
}
}
}
注意,第二个实现假定prodNameTrim()
的参数是一个类名(就像OP的版本一样)。
或者,如果每个选择器父级中只有一个链接标记,那么您可以简单地使用它,它应该适用于所有现代浏览器:
function prodNameTrim(rootClass) {
var items = document.querySelectorAll("." + rootClass + " a"), node;
for (var i = 0; i < items.length; i++) {
node = items[i].firstChild;
if (node.nodeValue.length > 26) {
node.nodeValue = node.nodeValue.substring(0, 27) + ' ...';
}
}
}
答案 2 :(得分:1)
如果你想在一行中进行条件截断,你可以这样做:
function prodNameTrim(selector){
var el = document.getElementsByClassName(selector),
len = el.length, node;
for(var i = 0; i < len; i++) {
node = el[i].getElementsByTagName('a')[0].firstChild;
node.nodeValue.substring(0, 27) + (node.nodeValue.length > 26 ? ' ...', '')
}
}
答案 3 :(得分:0)
你正在以正确的方式去做 - 除了你引入了一个不必要的全局变量。第一项任务应该是:
var txtNode = aObj[0].childNodes[0].nodeValue;
使用var
声明!您还可以在函数顶部的for
循环之前声明变量。如nnnnnn所述,您还要为i
和aObj
创建非预期的全局变量。所以你可以通过在for
循环之前插入这个问题来解决所有这三个问题:
var i, aObj, txtNode;