干掉htmlCollection到Array调用

时间:2016-06-27 15:10:25

标签: javascript arrays dry htmlcollection

我有一个当前在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语句之前定义它,因为元素尚未填充。因此,它尝试在空数组上运行代码并出错。

有什么建议吗?

2 个答案:

答案 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);