赋值变量新值以更改元素节点值
assigning variable new value to change element nodeValue
以下代码工作正常,但我想让它更好:
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 规则。
我会建议这样做:
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
中间,因为它不是必需的 - 避免使用textNode中间,因为它不是必需 的
- 直接赋值给节点值
- 仅在
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) + ' ...';
}
}
}
如果你只是想避免在任何地方重复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
变量。
如果你想在一行中做条件截断,你可以做这样的事情:
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 ? ' ...', '')
}
}
你这样做的方式是正确的——除了你引入了一个不必要的全局变量。第一个分配应该是:
var txtNode = aObj[0].childNodes[0].nodeValue;
使用 var
语句!您还可以在函数顶部的 for
循环之前声明变量。正如 nnnnnnn 所指出的,您还在为 i
和 aObj
创建意外的全局变量。因此,您可以通过在for
循环之前插入它来解决所有三个问题:
var i, aObj, txtNode;
- Javascript,将文本添加到具有现有文本节点的元素中
- jquery在元素中查找文本节点,并使用标记进行连接和包装
- js循环遍历单击的元素子节点
- 节点.js - 从 JSON 对象中删除空元素
- 如何保持所选元素's节点的值(而不是引用)
- 使用DOM树中的某种节点号进行元素搜索
- 使用 Sizzle 选择缓存节点的子元素
- 如何根据我正在读取的节点的元素名称创建元素
- 什么时候是“;“安全”;以在解析文档时修改给定的html元素/节点
- Javascript:更改元素节点
- 赋值变量新值以更改元素节点值
- 对象节点到元素节点的转换失败
- Javascript检查子节点是元素节点还是文本节点
- 在对对象进行字符串化处理时,JSON将元素节点转换为对象
- 如何访问react redux中的元素节点
- 仅使用Javascript访问iframe节点内给定的元素节点
- 当移动出包含的圆圈或文本时,将触发D3强制元素(节点)鼠标移出
- 如何最好地确定元素/节点在DOM中的距离
- 设置jquery的顶层元素节点
- 从JointJS元素/节点调用javascript/jquery函数