جاوا اسکریپت قدیمی و فناوریهای Legacy
AJAX و XMLHttpRequest، JSONP، jQuery و انتخابگرها و رویدادها و AJAX آن، APIهای قدیمی مرورگر و مهاجرت کدهای Legacy به جاوا اسکریپت مدرن.
چرا Legacy را یاد بگیریم؟
میلیونها خط کد قدیمی هنوز فعال است — برای نگهداری، درک و مهاجرت لازم است:
- پروژههای قدیمی که باید نگهداری کنید
- فهم پاسخهای Stack Overflow قدیمی
- قدردانی اینکه چرا ابزارهای مدرن ساخته شدند!
AJAX — آغاز تعامل
AJAX (Asynchronous JavaScript and XML) در ۲۰۰۵ انقلاب بود — بارگذاری داده بدون رفرش:
// AJAX کلاسیک با XHR:
function oldAjax() {
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // کامل
if (xhr.status === 200) { // موفق
console.log(xhr.responseText);
}
}
};
xhr.send();
}
XMLHttpRequest — کامل
const xhr = new XMLHttpRequest();
// آمادهسازی:
xhr.open("POST", "/api/users", true);
xhr.setRequestHeader("Content-Type", "application/json");
// پاسخ:
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
const data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error("خطا:", xhr.status);
}
};
xhr.onerror = function () {
console.error("خطای شبکه");
};
// پیشرفت — مزیت XHR:
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
console.log((e.loaded / e.total * 100) + "%");
}
};
// ارسال:
xhr.send(JSON.stringify({ name: "علی" }));
// لغو:
xhr.abort();
readyState — حالتها
| مقدار | وضعیت |
|---|---|
| 0 | UNSENT — open نشده |
| 1 | OPENED — open شده |
| 2 | HEADERS_RECEIVED |
| 3 | LOADING — در حال دریافت |
| 4 | DONE — تمام |
XML — قدیمیترین فرمت
// پاسخ XML (قبل از JSON):
// <users>
// <user id="1">
// <name>علی</name>
// </user>
// </users>
// پارس XML:
const xmlText = xhr.responseText;
const parser = new DOMParser();
const doc = parser.parseFromString(xmlText, "text/xml");
// پیمایش مثل DOM:
const users = doc.querySelectorAll("user");
users.forEach(user => {
console.log(user.querySelector("name").textContent);
});
// ساخت XML:
const xml = `<?xml version="1.0"?>
<user><name>علی</name></user>`;
JSONP — دور زدن CORS قدیم
قبل از CORS — با تگ script بیندامنه:
// سرور به جای JSON — کد JS برمیگرداند:
// handleData({"name": "علی"});
// کلاینت:
function handleData(data) {
console.log("دریافت:", data);
}
const script = document.createElement("script");
script.src = "https://api.other.com/data?callback=handleData";
document.body.appendChild(script);
// یا با jQuery:
// $.ajax({
// url: "https://api.other.com/data",
// dataType: "jsonp",
// success: handleData
// });
JSONP ناامن است — سرور میتواند هر کدی اجرا کند. امروزه منسوخ!
jQuery — پادشاه گذشته
روزی ۸۰٪ وب! حل مشکلات سازگاری مرورگرها:
// انتخابگر — $ معروف:
$(".my-class"); // همه
$("#my-id"); // با ID
$("ul li:first"); // CSS selector
// رویداد:
$("#btn").on("click", function () {
alert("کلیک!");
});
// حتی زنجیرهای:
$("#box")
.css("color", "red")
.addClass("active")
.fadeIn()
.html("سلام");
DOM در jQuery
// محتوا:
$("#el").html("<b>متن</b>"); // innerHTML
$("#el").text("متن ساده"); // textContent
$("#el").val(); // مقدار input
// ساخت:
const el = $("<div>", {
class: "item",
text: "سلام",
click: () => alert("کلیک")
});
$("body").append(el);
// پنهان/نمایش:
$("#el").hide();
$("#el").show();
$("#el").toggle();
$("#el").fadeIn(500);
$("#el").slideUp();
// CSS:
$("#el").css({ color: "red", margin: "10px" });
$("#el").addClass("active");
$("#el").hasClass("active"); // true
AJAX در jQuery
// $.ajax — کامل:
$.ajax({
url: "/api/users",
method: "GET",
data: { page: 1, limit: 10 }, // query string خودکار
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (xhr, status, err) {
console.error(err);
}
});
// میانبرها:
$.get("/api/users", function (data) {
console.log(data);
});
$.post("/api/users", { name: "علی" }, function (data) {
console.log("ایجاد شد:", data);
});
$.getJSON("/api/data", function (data) {
// خودکار پارس JSON
});
پویایی و انیمیشن jQuery
// animate:
$("#box").animate({
left: "+=100px",
opacity: 0.5
}, 500);
// هر عنصر:
$("li").each(function (i) {
console.log(i, $(this).text());
});
// DOM traversal:
$("li").parent();
$("li").eq(2); // سومی
$("li").first();
$("li").filter(".active");
$("li").find("span");
APIهای قدیمی مرورگر
// شناختن برای کدهای قدیمی:
// company prefixها:
// webkitRequestAnimationFrame
// mozRequestAnimationFrame
// msRequestFullscreen
// document.write — قدیمی و مضر:
document.write("<h1>سلام</h1>"); // پس از load صفحه را خراب میکند!
// innerHTML برای سازگاری:
el.innerHTML = "<b>قدیمی</b>"; // هنوز کار میکند
// event قدیمی:
element.onclick = function () {}; // فقط یک هندلر!
element.attachEvent("onclick", fn); // IE قدیمی
// getComputedStyle:
// window.getComputedStyle(el).color;
مهاجرت به مدرن — راهنمای تبدیل
| jQuery | جاوا اسکریپت مدرن |
|---|---|
$(".x") | document.querySelector(".x") |
$("#x").text() | el.textContent |
$("#x").html() | el.innerHTML |
$("#x").on("click", fn) | el.addEventListener("click", fn) |
$("#x").addClass("a") | el.classList.add("a") |
$("#x").css("color", "red") | el.style.color = "red" |
$("#x").hide() | el.hidden = true |
$("#x").append(el) | el.append(child) |
$.each(arr, fn) | arr.forEach(fn) |
$.ajax({...}) | fetch(url, opts) |
$.getJSON(url) | fetch(url).then(r => r.json()) |
نمونه مهاجرت کامل
// ❌ jQuery قدیمی:
// $(document).ready(function () {
// $("#loadUsers").click(function () {
// $.getJSON("/api/users", function (users) {
// var html = "";
// $.each(users, function (i, user) {
// html += "<li>" + user.name + "</li>";
// });
// $("#userList").html(html).hide().fadeIn();
// });
// });
// });
// ✓ JS مدرن:
document.addEventListener("DOMContentLoaded", async () => {
document.querySelector("#loadUsers")
.addEventListener("click", async () => {
const res = await fetch("/api/users");
const users = await res.json();
document.querySelector("#userList").replaceChildren(
...users.map(user => {
const li = document.createElement("li");
li.textContent = user.name; // امن از XSS!
return li;
})
);
});
});
استراتژی مهاجرت
- ارزیابی: کجا jQuery استفاده شده؟
- تست بنویسید — قبل از تغییر رفتار فعلی را قفل کنید
- تدریجی: بخش به بخش — نه همه با هم
- ابزارها: eslint-plugin-jquery — هشدار استفاده
- حذف وابستگی: بعد از صفر شدن استفاده — drop!
چه چیزی ارزش مهاجرت دارد؟
| بله — مهاجرت کن | نه — نگه دار |
|---|---|
| پروژه فعال در توسعه | پروژه آرشیوشده |
| کارایی مهم | jQuery کار میکند |
| کوچک و قابل تست | وابستگی سنگین به افزونهها |
| تیم آشنا به مدرن | تیم فقط jQuery |
جمعبندی
- XHR و jQuery را بشناسید — برای کدهای قدیمی
- fetch و APIهای مدرن را بنویسید
- مهاجرت تدریجی با تست
- Legacy برای فهم، مدرن برای آینده
این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.