我有一个当前在JavaScript中使用.getElementBy...
DOM调用的函数。
var $ = function (selector) {
var elements = [];
var lastSelector = selector.substring(selector.search(/[^#.]+$/), selector.length);
if(selector.includes('#') !== true || selector.includes('.') !== true) {
elements.push(document.getElementsByTagName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);
}
return elements;
};
使用代码在函数中有许多其他if语句:
elements.push(document.getElementsByTagName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);
或
elements.push(document.getElementsByClassName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);
理想情况下,我想干掉重复:
elements = Array.prototype.slice.call(elements[0]);
但我无法在if
语句之前定义它,因为元素尚未填充。因此,它尝试在空数组上运行代码并出错。
有什么建议吗?
答案 0 :(得分:1)
您可以使用所有浏览器(包括IE8 +)中提供的标准querySelectorAll()
,而不是使用自制限制功能来选择元素。
至于将类似数组的对象(例如DOM集合)转换为真实的Array
(代码中使用Array.prototype.slice.call()
),我使用以下函数: / p>
var arrayFrom = function(arrayLike) {
if (Array.from) {
return Array.from(arrayLike);
}
var items;
try {
items = Array.prototype.slice.call(arrayLike, 0);
}
catch(e) {
items = [];
var count = arrayLike.length;
for (var i = 0; i < count; i++) {
items.push(arrayLike[i]);
}
}
return items;
};
或以下简化版本,如果浏览器不支持将非Array
参数传递给Array.prototype.slice.call()
(IE8-如果我没记错的话)并不重要:
var arrayFrom = function(arrayLike) {
return Array.from
? Array.from(arrayLike);
: Array.prototype.slice.call(arrayLike, 0);
};
答案 1 :(得分:0)
当然可以考虑@marat-tanalin的回答。在使用querySelectorAll()
不是一个选项的情况下,以下对我有用,感谢@ master565的帮助:
首先,包裹行:
elements.push(document.getElementsByTagName(lastSelector));
elements = Array.prototype.slice.call(elements[0]);
在一个函数中:
function pushByTag(selector) {
elements.push(document.getElementsByTagName(selector));
elements = Array.prototype.slice.call(elements[0]);
}
干得很多。然后为if
参数设置变量有很大帮助:
if(selector.includes('#') !== true || selector.includes('.') !== true)
成为:
var noClassOrId = selector.includes('#') !== true || selector.includes('.') !== true;
这两个重构都允许我将我的if
语句单行添加到我认为相当可读的内容中:
if (noClassOrId) pushByTag(lastSelector);