将简单的jQuery重写为纯JavaScript

时间:2014-07-28 17:37:06

标签: javascript jquery code-translation

我正在构建一个可以插入其他网站的JavaScript插件。

整个事情是用纯粹的JS编写的,但有一点我无法通过jQuery摆脱:

var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";
jQuery(document).on('change', selector, function() {
    doSomething(key, this.value);
});

我想避免jQuery的原因是我希望这个JS被包含在各种各样的站点中,其中许多站点都没有jQuery。有些人已经安装了其他框架,比如Mootools,有些框架会有旧版本的jQuery,.on()不支持等等。

那,我理想地试图保持它非常轻量级,所以为这个小任务添加jQuery似乎过度。

1 个答案:

答案 0 :(得分:7)

这是一些完全相同的未来主义JavaScript:

var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";

document.addEventListener('change', function (e) {
    if (e.target.matches(selector)) {
        doSomething(key, e.target.value);
    }
});

然而,several browsers only support it with a prefix,所以它会更接近于此:

var matches = (function () {
    var names = ['matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector'];

    for (var i = 0; i < names.length; i++) {
        var name = names[i];

        if (name in HTMLElement.prototype) {
            return HTMLElement.prototype[name];
        }
    }

    return null;
})();

var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";

document.addEventListener('change', function (e) {
    if (matches.call(e.target, selector)) {
        doSomething(key, e.target.value);
    }
});

假设选择器不是动态的并且您需要委派,您仍然可以进行详细的手动检查:

var key = "some_key";

document.addEventListener('change', function (e) {
    var target = e.target;

    if (target.id === 'my_input' ||
            target.nodeName === 'INPUT' && target.name === 'my_input' ||
            (' ' + target.className + ' ').indexOf(' someInputs ') !== -1) {
        doSomething(key, target.value);
    }
}, false);

作为@ T.J。 Crowder指出,尽管这适用于输入元素,但在许多情况下,您需要检查元素的父元素。这里有一些更具未来感的JavaScript来完成任务:

function* ascend(element) {
    do {
        yield element;
    } while ((element = element.parentNode));
}

var key = "some_key";
var selector = "#my_input, input[name=my_input], .someInputs";

document.addEventListener('change', function (e) {
    var match = Array.from(ascend(e.target)).find(x => x.matches(selector));

    if (match) {
        doSomething(key, match.value);
    }
});

如果你将Firefox Nightly和Chrome混合在一起,这将在该浏览器中运行。我们没有那个,但可以随意填充Array.prototype.find