JavaScript >> Javascript 文檔 >  >> jQuery

不使用 jQuery 編寫 JavaScript 的 10 個技巧

jQuery 是一個很棒的庫。大約在 IE6 成為排名第一的瀏覽器的時候。那時,有一些怪癖和差異需要解決,而 jQuery 是編寫跨瀏覽器代碼的完美工具。

然而,今天,Web 瀏覽器比那些日子有了很大進步。我們可以輕鬆地使用 ES5 提供的所有功能,並且我們可以使用很棒的 HTML5 API,這些 API 使與 DOM 的工作變得更好。開發人員現在可以選擇在某些項目中不使用 jQuery,同時仍然保持生產力。

不要誤會我的意思——jQuery 仍然是一個很棒的庫,而且大多數情況下你會更好地使用它。但是,對於像 JS 交互有限的簡單頁面、瀏覽器擴展和移動網站等較小的事情,您可以使用 vanilla JS。這裡有 10 條提示,可以幫助您努力。

1。聆聽文件準備就緒

編寫 jQuery 時要做的第一件事是將代碼包裝在 $(document).ready() 中 調用,以便您知道 DOM 何時準備好進行操作。如果沒有 jQuery,我們就會有 DOMContentLoaded 事件。以下是它的使用方法:

// Add an event listener of DOMContentLoaded to the whole document and call an anonymous function.
// You can then wrap your code in that function's brackets
// and it will execute once loading is complete.

document.addEventListener('DOMContentLoaded', function () {

    // Our hawaiian greeting is displayed as soon as the page loads,

    console.log('Aloha');

});

2。選擇元素

曾幾何時,我們只能通過 id、class 和標籤名稱來選擇元素,而 jQuery 憑藉其類似 css 的智能選擇器成為了救命稻草。從那以後,瀏覽器開始流行起來,並引入了兩個重要的 API - querySelector 和querySelectorAll:

// We can use document.querySelector to get the first element that matches a certain criteria.
// It's only argument is a string containing one or more CSS selectors.

var lochNess = document.querySelector(".monsters");

console.log("It's from Scotland - " + lochNess.textContent);

// We can also get all elements of a certain type or class by using document.querySelectorAll.
// This returns a NodeList of all the elements that fit our criteria.

var scary = document.querySelectorAll(".monsters");

console.log("Hide and seek champions: ");

for (var i = 0; i < scary.length; i++) {

    console.log(scary[i].innerHTML);

}
<ul>

    <li class="monsters">Nessy</li>

    <li class="monsters">Big foot</li>

    <li class="monsters">La chupacabra</li>

</ul>

3。附加和移除事件監聽器

監聽事件是構建 Web 應用程序的基本部分。曾經有兩個主要陣營在如何完成這一點上有所不同 - IE 和其他陣營。但是今天我們只使用 addEventListener

var btn = document.querySelectorAll("button"),
    list = document.querySelector("ul");

// We call the addEventListener method on our desired event target(in this case a button).
// This will start a listener that will wait until a click is generated on the element.

btn[0].addEventListener("click", function () {

    // When this button is clicked we want to enable zooming of our list.

    // To do this we add an event listener to our list itself,
    // so when the cursor hovers it, the enlarge function gets called.

    list.addEventListener("mouseover", enlarge);
});

// To disable the zooming we can simply use removeEventListener.

btn[1].addEventListener("click", function () {

    // Removing event listeners doesn't work on anonymous functions, so always use a named one.

    list.removeEventListener("mouseover", enlarge);
});

// Let's create our enlarge function.

var enlarge = function () {

    // Add class zoomed to the unordered list.

    list.classList.add("zoomed");

    // When the cursor leaves the list return to normal size by removing the class.

    list.addEventListener("mouseout", function () {

        list.classList.remove("zoomed")

    });

};

// Now we want to be able to color the names by clicking them.

// When a 'click' is registered on one of the list entries it should change its color to green.
// Thanks to event delegation we can actually add an event listener to the whole parent object.
// This way we don't have to add separate event listeners to each <li>.

list.addEventListener("click", function (e) {

    // Make the coloring happen only to the clicked element by taking the target of the event.

    e.target.classList.add('green');

});
<button>Enable zoom</button>

<button>Disable zoom</button>

<br><br>

Click on any of the names to color them green

<ul>

    <li>Chewbacca</li>

    <li>Han Solo</li>

    <li>Luke</li>

    <li>Boba fett</li>

</ul>
.green {
    color: green;
}

.zoomed {
    cursor: pointer;
    font-size: 23px;
}

addEventListener 過去需要第三個參數(useCapture),但這已經有一段時間了。因此,代碼看起來更像 jQuery。

4。操作類和屬性

在沒有 jQuery 的情況下操作元素的類名過去非常不方便。不用了,多虧了 classList 屬性。如果你需要操作屬性,你有 setAttribute。

var btn = document.querySelectorAll("button"),
    div = document.querySelector("#myDiv");

btn[0].addEventListener("click", function () {

    // Get any attribute easily.
    console.log(div.id);
});

// Element.classList stores all classes of the element in the form of a DOMTokenList.

var classes = div.classList;

btn[1].addEventListener("click", function () {

    console.log(classes);

});

btn[2].addEventListener("click", function () {

    // It supports adding and removing classes.
    classes.add("red");

});

btn[3].addEventListener("click", function () {

    // You can also toggle a class on and off
    classes.toggle("hidden");

});
<div id='myDiv' class="square"></div>

<button>Display id</button>

<button>Display classes</button>
<button>Color red</button>
<button>Toggle visibility</button>
.square {
    width: 100px;
    height: 100px;
    margin-bottom: 20px;
    border: 1px solid grey;
    border-radius: 5px;
}

.hidden {
    visibility: hidden;
}

.red {
    background-color: red;
}

5。獲取和設置元素內容

jQuery 有方便的 text() 和 html() 方法。取而代之的是我們已經使用了很長時間的 textContent 和 innerHTML 屬性:

var myText = document.querySelector("#myParagraph"),
    btn = document.querySelectorAll("button");

// We can easily get the text content of a node and all its descendants.

var myContent = myText.textContent;

console.log("textContent:  " + myContent);

// When using textContent to alter the text of an element
// it deletes the old content and replaces it with new.

btn[0].addEventListener('click', function () {

    myText.textContent = " Koalas are the best animals ";

});

// If we want to grab all the HTML in a node (including the tags) we can use innerHTML.

var myHtml = myText.innerHTML;

console.log("innerHTML:  " + myHtml);

// To change the html simply supply new content.
// Of course we aren't limited to text only this time.

btn[1].addEventListener('click', function () {

    myText.innerHTML = "<button> Penguins are the best animals </button>";

});
<p id="myParagraph"><strong> Which are the best animals? </strong></p>

<button>Koalas</button>

<br>

<button>Penguins</button>

6。插入和刪除元素

儘管 jQuery 使它變得更容易,但使用純 JavaScript 添加和刪除 DOM 元素並非不可能。以下是如何添加、刪除和替換您想要的任何元素:

var lunch = document.querySelector("#lunch");

// In the HTML tab we have our lunch for today.

// Let's say we want to add fries to it.

var addFries = function () {

    // First we have to create our new element and set its content

    var fries = document.createElement("div");
    fries.innerHTML = '<li><h4> Fries </h4></li>';

    // After that's done, we can use appendChild to insert it.
    // This will make our fries appear at the end of the lunch list.

    lunch.appendChild(fries);

};

// Now we want to add cheese both before and after the beef in our burger.

var addCheese = function () {

    var beef = document.querySelector("#Beef"),

            topSlice = document.createElement("li"),
            bottomSlice = document.createElement("li");

    bottomSlice.innerHTML = topSlice.innerHTML = 'Cheese';

    // Inserting the top slice:
    // Take the parent of the beef (that's the sandwich) and use insertBefore on it.
    // The first argument to insertBefore is the new element we're gonna add.
    // The second argument is the node before which the new element is inserted.

    beef.parentNode.insertBefore(topSlice, beef);

    // The bottom slice:
    // We have to use a little trick here!
    // Supply the next nearest element as the second argument to insertBefore,
    // that way we can actually insert after the element we want.

    beef.parentNode.insertBefore(bottomSlice, beef.nextSibling);

};

var removePickles = function () {

    // Finally, we want to get rid of those pickles. Again javascript got us covered!

    var pickles = document.querySelector("#pickles");

    if (pickles) {
        pickles.parentNode.removeChild(pickles);
    }

};

// Delicious!

var btn = document.querySelectorAll("button");

btn[0].addEventListener('click', addFries);

btn[1].addEventListener('click', addCheese);

btn[2].addEventListener('click', removePickles);
<button>Add fries to lunch</button>
<button>Add cheese to sandwich</button>
<button>Remove pickles</button>

<h3>My Lunch</h3>
<ul id="lunch">
    <li><h4>My sandwich</h4></li>
    <li>Bread</li>
    <li id="pickles">Pickles</li>
    <li id="Beef">Beef</li>
    <li>Mayo</li>
    <li>Bread</li>
</ul>

7。遍歷 DOM 樹

每個真正的 JS 忍者都知道,DOM 中隱藏著很多力量。與 jQuery 相比,普通 DOM API 提供的選擇祖先或兄弟姐妹的功能有限。但是,您仍然可以做很多事情來穿越這棵樹。

var snakes = document.querySelector('#snakes'),
    birds = document.querySelector('#birds');

snakes.addEventListener('click', function (e) {

    // To access the parent of a certain element in the DOM tree, we use the parentNode method.

    var parent = e.target.parentNode;

    console.log("Parent: " + parent.id);

    // For the opposite, calling the .children method gets all child elements of the selected object.

    console.log("Children: ");
    var children = e.target.children;

    // This returns a HTMLCollection (a type of array), so we have to iterate to access every child's content.

    for (var i = 0; i < children.length; i++) {

        console.log(children[i].textContent);

    }
});

birds.addEventListener('click', function (e) {

    // Getting the nearest sibling to our element is self-explanatory.

    var previous = e.target.previousElementSibling;

    if (previous) {
        console.log("Previous sibling: " + previous.textContent);

    }

    var next = e.target.nextElementSibling;

    if (next) {
        console.log("Next sibling: " + next.textContent);

    }

    // However, to acquire all the siblings of a node is a bit more complex.
    // We have to take all of its parent's children and then exclude the original element.
    // This is done by using filter and calling a function that checks every child one by one.

    console.log("All siblings: ");

    Array.prototype.filter.call(e.target.parentNode.children, function (child) {
        if (child !== e.target) {
            console.log(child.textContent);
        }
    });

});
Click on the objects to see their parent and children elements
<div id="snakes">
    Snakes

    <ul id="venomous">
        Venomous
        <li>Cobra</li>
        <li>Rattlesnake</li>
    </ul>

    <ul id="non-venomous">
        Non venomous
        <li>Python</li>
        <li>Anaconda</li>
    </ul>

</div>

Click on any of the birds to see its siblings
<div>
    Birds
    <ul id="birds">
        <li>Flamingo</li>
        <li>Seagull</li>
        <li>Raven</li>
        <li>Dodo</li>
    </ul>
</div>
div {
    color: white;
    background-color: #93d0ea;
    font-family: sans-serif;
    width: 180px;
    text-align: center;
    padding: 10px;
    margin: 5px;
}

8。遍歷數組

jQuery 提供的一些實用方法在 ES5 標準中可用。對於迭代數組,我們可以使用 forEach 和 map 而不是它們的 jQuery 版本 - each()map() .請注意參數和默認值的差異 this 回調中的值。

var ninjaTurtles = ["Donatello", "Leonardo", "Michelangelo", "Raphael"];

// ForEach automatically iterates through an array.

ninjaTurtles.forEach(function (entry) {
    console.log(entry);
});

// The map method calls a function on every element of an array and creates a new array with the results.

var lovesPizza = ninjaTurtles.map(function (entry) {

    return entry.concat(" loves pizza!");

});

console.log(lovesPizza);

9。動畫

jQuery 的 animate 方法優於您可以自己粘合在一起的任何方法,如果您的應用程序中需要復雜的可編寫腳本的動畫,您仍然應該堅持使用它。但是由於 CSS3 的所有奇蹟,一些簡單的情況可以使用像 Animate.css 這樣的輕量級庫來處理,它使您能夠通過向元素添加或刪除類名來觸發動畫。

var btn = document.querySelectorAll("button"),
        circle = document.querySelector("#circle");

// First, we have to add a class of animated to our object, so the library can recognize it.

circle.classList.add('animated');

// We iterate over all of our buttons and add event listeners to each one.

for (var i = 0; i < btn.length; i++) {

    // Define an anonymous function here, to make it possible to use the i variable.

    (function (i) {

        btn[i].addEventListener('click', function () {

            // To start an animation you just have to add a specific class to the object.
            // In our case we stored the classes' names in the data-animation attribute of each button.

            var animation = btn[i].getAttribute('data-animation');

            circle.classList.add(animation);

            // To make it work more then once we have to remove the class after the animation is complete.

            window.setTimeout(function () {

                circle.classList.remove(animation);

            }, 1000);

        });

    }(i));

}
<button data-animation="bounce">Bounce</button>
<button data-animation="pulse">Pulse</button>
<button data-animation="fadeInLeftBig">Fade in</button>
<button data-animation="fadeOutRightBig">Fade out</button>
<button data-animation="flip">Flip</button>

<div id="circle"></div>
body {
    text-align: center;
}

#circle {
    border-radius: 50%;
    margin: 50px auto;
    width: 50px;
    height: 50px;
    background-color: #93d0ea;
}

10. AJAX

AJAX 是另一種曾經是跨瀏覽器混亂的技術。好消息是我們現在可以在任何地方使用相同的代碼。壞消息是,使用 XMLHttpRequest 實例化和發送 AJAX 請求仍然很麻煩,因此最好將其留給庫。但是你不需要僅僅為此包含整個 jQuery。您可以使用眾多可用的輕量級庫之一。這是一個直接構建 AJAX 請求的示例,並且使用了小的 reqwest 庫:

// This simple example logs the body of our url (a html file) in the console.

// It's possible to do a manual GET request but it is somewhat a tedious task.

var request = new XMLHttpRequest();
request.open('GET', 'https://tutorialzine.com/misc/files/my_url.html', true);

request.onload = function (e) {
    if (request.readyState === 4) {

        // Check if the get was successful.

        if (request.status === 200) {
            console.log(request.responseText);
        } else {
            console.error(request.statusText);
        }
    }
};

// Catch errors:

request.onerror = function (e) {
    console.error(request.statusText);
};

request.send(null);

// Using a small library, such as Reqwest, can make your job much easier.

reqwest({
    url: 'https://tutorialzine.com/misc/files/my_url.html',
    method: 'get',
    error: function (err) {
    },
    success: function (resp) {
        console.log(resp);
    }
});

結論

爭取最小化、零膨脹的網頁是一個有價值的目標,它將以更快的加載時間和更好的用戶體驗來回報自己。不過你應該小心——如果你重新發明 jQuery 給你的輪子,沒有人會贏。不要僅僅為了減少字節計數而犧牲良好的開發實踐。但是有很多地方可以完全適用今天的技巧。下次試試香草味,它可能就是你所需要的!


Tutorial JavaScript 教程
  1. 2017 年 2 月 DoneJS 社區更新

  2. 如何學習 React(以及在此過程中構建什麼)

  3. 當我想構建一個基於現有 JS 的 React App 時,我應該從哪裡開始?

  4. 讓 JAVASCRIPT !!

  5. 如何在基於html的網站中添加konami代碼?

  6. React 路線圖:2021 年成為 React 開發人員的 10 個步驟

  7. 個人網站 - DO Hackaton 提交

  1. 完整的 React 生態系統學習

  2. SPA 和可訪問性的問題......以及如何解決它

  3. 使用 React、Vite 和 Tailwind 設置開發環境

  4. 使用 Axios 和 fetch API 在 Vue 2 中處理 AJAX 請求

  5. 使用 Typescript 的 useContext()

  6. 為什麼我從這個 JSON 對像中得到“未定義”? [關閉]

  7. 咖哩怎麼了?

  1. React 中的 PropType 是什麼?

  2. 🧶 React 中的隱式 CLSX

  3. 2022 年使用的 60 個很棒的 Web 開發工具

  4. 語義 UI React 模式中的表單