0

我有一个当前正在使用.getElementBy...JavaScript 中的 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语句之前定义它,因为尚未填充元素。因此,它尝试在空数组和错误上运行代码。

有什么建议么?

4

2 回答 2

1

querySelectorAll()您可以使用所有浏览器(包括 IE8+)中可用的标准,而不是使用自制的有限功能来通过选择器选择元素。

至于将类似数组的对象(例如 DOM 集合)转换为真实的ArrayArray.prototype.slice.call()在您的代码中使用的对象),我使用以下函数:

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);
};
于 2016-06-27T22:47:35.203 回答
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);
于 2016-06-28T11:34:39.590 回答