jQuery to Vanilla JS - querySelector问题

时间:2017-12-07 09:10:13

标签: javascript jquery

我正在浏览一些代码并努力将所有jQuery更改为vanilla JS。但是有一个部分我在控制台中不断收到错误:

  

TypeError:document.querySelectorAll(...)。toggle不是函数pr   TypeError:document.querySelectorAll(...)为null

下面是我的代码,你可以看到的顶部是我试图将jquery更改为vanilla js(我已经注释掉了jquery):

console.log(shipmentNumbers);
            for (let i = 0; i < shipmentNumbers.length; i += 1) {
                let sNumber = shipmentNumbers[i];

                function getHistory(event) {
                    console.log(event);
                    document.querySelectorAll('#shipment' + sNumber + 'tr.show-history' + sNumber).toggle();
                    // $('#shipment' + sNumber + ' tr.show-history' + sNumber).toggle();
                    document.getElementsByClassName('overlay-line' + sNumber).style.display = 'table-row';
                    // $('.overlay-line' + sNumber).css({
                    //  "display": "table-row"
                    // });
                    if (flag == false) {
                        let shipmentNumber = event.currentTarget.id.replace('status', '');
                        console.log('shipmentNumber=', shipmentNumber);
                        callHistoryApi(clientId, shipmentNumber);
                        $(this).find('.expand' + sNumber).html("&#9660;");
                        flag = true;
                    } else {
                        $(this).find('.expand' + sNumber).html("&#9658;");
                        $('.overlay-line' + sNumber).css({
                            "display": "none"
                        });
                        flag = false;
                    }
                } 

有人可以解释为什么这不起作用,以及如何使用vanilla js让它工作?

2 个答案:

答案 0 :(得分:2)

我发现编写这两个函数在从jQuery转换到本机JS时确实很有帮助。

function domEach(selector, handler, context) {
    return Array.from(document.querySelectorAll(selector), handler, context);
}

// If you get a TypeError "Array.from" is not a function, use the polyfill
// found on MPN.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

这可以解决您依赖jQuery使用的隐式循环的问题。

// Instead of these:

document.querySelectorAll('#shipment' + sNumber + 'tr.show-history' + sNumber).toggle();
document.getElementsByClassName('overlay-line' + sNumber).style.display = 'table-row';

// Use these:

domEach('#shipment' + sNumber + 'tr.show-history' + sNumber, function (tr) {

    tr.style.display = tr.style.display === "none"
        ? ""
        : "none";

});

domEach('.overlay-line' + sNumber, function (el) {
    el.style.display = 'table-row';
});

有关使用的技术列表而不是jQuery函数,您可以检查You Might Not Need jQuery

修改:有关上述代码的更多信息

jQuery使用隐式循环。也就是说,当你这样做时:

$("#one").addClass("two");

jQuery在幕后做到了这一点:

var elements = document.querySelectorAll("#one");
var i = 0;
var il = elements.length;
while (i < il) {
    elements[i].classList.add("two");
    i += 1;
}

当从jQuery转到vanilla JavaScript时,这会导致一些混淆,因为你必须手动循环querySelectorAll的结果。

Array.from将遍历数组或类似数组的结构。 querySelectorAll将返回NodeList - 这是一个类似数组的结构(它有数字标记和length属性)。 domEach函数允许我们将CSS选择器传递给函数,并循环查找匹配元素的结果。

? :语法称为三元运算符。这是if ... else的捷径。

// Ternary operator
tr.style.display = tr.style.display === "none"
    ? ""
    : "none";

// Equivalent if/else statements
if (tr.style.display === "none") {
    tr.style.display = "";
} else {
    tr.style.display = "none";
}

我希望这有助于澄清事情。

答案 1 :(得分:-1)

每次执行此操作时都必须添加签入,因为.querySelctor / All()将返回&#34; null&#34;如果没有找到任何元素。

var myCollection = document.querySelectorAll("selector");
if (myCollection.length > 0){
   Array.prototype.forEach.call(myCollenction, function(element){
      if(typeof element.toggle === "function"){
         element.toggle();
      }
   })
}

这或多或少会帮助您实现目标。但是,如果你没有方法&#34;切换&#34;在你的元素上定义 - 什么都不会发生。 :)