درس ۱۶: دستکاری DOM

یادگیری تعامل با عناصر HTML از طریق JavaScript

درس ۱۶ از ۲۰
پیشرفت درس

DOM چیست؟

DOM مخفف Document Object Model است و نمایش درختی از ساختار HTML صفحه وب می‌باشد. JavaScript از طریق DOM می‌تواند با عناصر HTML تعامل کرده، آن‌ها را تغییر دهد، حذف کند یا عناصر جدید اضافه کند.

قابلیت‌های دستکاری DOM:

  • انتخاب و دسترسی به عناصر HTML
  • تغییر محتوا و ویژگی‌های عناصر
  • تغییر استایل‌ها و کلاس‌های CSS
  • اضافه کردن و حذف عناصر
  • پیمایش و جستجو در ساختار صفحه

انتخاب عناصر

روش‌های مختلف انتخاب

۱. انتخاب بر اساس ID

const element = document.getElementById('myId');
console.log(element);

۲. انتخاب بر اساس کلاس

const elements = document.getElementsByClassName('myClass');
console.log(elements); // HTMLCollection

۳. انتخاب بر اساس تگ

const paragraphs = document.getElementsByTagName('p');
console.log(paragraphs);

۴. انتخاب با CSS Selector

// انتخاب اولین عنصر
const firstElement = document.querySelector('.myClass');

// انتخاب همه عناصر
const allElements = document.querySelectorAll('.myClass');

تمرین عملی: دستکاری DOM

در ادامه، انواع مختلف دستکاری DOM را تمرین کنید:

ویرایشگر کد خط 1، ستون 1
نمایش زنده

تغییر محتوا و ویژگی‌ها

تغییر محتوای متنی

// تغییر متن
element.textContent = "متن جدید";

// تغییر HTML
element.innerHTML = "<strong>متن ضخیم</strong>";

// دریافت محتوا
const content = element.textContent;

کار با ویژگی‌ها (Attributes)

// تنظیم ویژگی
element.setAttribute('class', 'new-class');
element.setAttribute('data-id', '123');

// دریافت ویژگی
const className = element.getAttribute('class');

// حذف ویژگی
element.removeAttribute('data-id');

// بررسی وجود ویژگی
if (element.hasAttribute('class')) {
    console.log('کلاس دارد');
}

کار با کلاس‌های CSS

// اضافه کردن کلاس
element.classList.add('new-class');

// حذف کلاس
element.classList.remove('old-class');

// تغییر وضعیت کلاس
element.classList.toggle('active');

// بررسی وجود کلاس
if (element.classList.contains('active')) {
    console.log('کلاس active دارد');
}

تغییر استایل‌ها

تغییر مستقیم استایل

// تغییر رنگ
element.style.color = 'red';
element.style.backgroundColor = '#f0f0f0';

// تغییر اندازه
element.style.width = '200px';
element.style.height = '100px';

// تغییر موقعیت
element.style.position = 'absolute';
element.style.top = '50px';
element.style.left = '100px';

// چندین استایل همزمان
Object.assign(element.style, {
    color: 'blue',
    fontSize: '18px',
    fontWeight: 'bold'
});

دریافت استایل‌های محاسبه شده

const computedStyle = window.getComputedStyle(element);
const color = computedStyle.color;
const fontSize = computedStyle.fontSize;

console.log('رنگ فعلی:', color);
console.log('اندازه فونت:', fontSize);

ایجاد و حذف عناصر

ایجاد عناصر جدید

// ایجاد عنصر جدید
const newDiv = document.createElement('div');
newDiv.textContent = 'عنصر جدید';
newDiv.className = 'new-element';

// ایجاد عنصر با HTML
const container = document.createElement('div');
container.innerHTML = `
    <h3>عنوان</h3>
    <p>این یک پاراگراف است</p>
`;

// اضافه کردن به صفحه
document.body.appendChild(newDiv);

// اضافه کردن به عنصر خاص
const parent = document.getElementById('container');
parent.appendChild(container);

روش‌های مختلف اضافه کردن

const parent = document.getElementById('parent');
const newElement = document.createElement('p');
newElement.textContent = 'پاراگراف جدید';

// اضافه کردن در انتها
parent.appendChild(newElement);

// اضافه کردن در ابتدا
parent.insertBefore(newElement, parent.firstChild);

// اضافه کردن قبل از عنصر خاص
const referenceElement = document.getElementById('reference');
parent.insertBefore(newElement, referenceElement);

// اضافه کردن با insertAdjacentHTML
parent.insertAdjacentHTML('beforeend', '<p>HTML جدید</p>');

حذف عناصر

// حذف عنصر
element.remove();

// حذف از والد
parent.removeChild(element);

// حذف همه فرزندان
parent.innerHTML = '';

// حذف با شرط
const items = document.querySelectorAll('.item');
items.forEach(item => {
    if (item.textContent.includes('حذف')) {
        item.remove();
    }
});

پیمایش DOM

دسترسی به عناصر مرتبط

const element = document.getElementById('myElement');

// والد
const parent = element.parentElement;
const parentNode = element.parentNode;

// فرزندان
const children = element.children; // HTMLCollection
const childNodes = element.childNodes; // NodeList (شامل text nodes)
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;

// خواهر و برادر
const nextSibling = element.nextElementSibling;
const prevSibling = element.previousElementSibling;

جستجو در DOM

// جستجو در فرزندان
const childElement = parent.querySelector('.child-class');
const allChildren = parent.querySelectorAll('.child-class');

// جستجو در والدین
function findParentWithClass(element, className) {
    let current = element.parentElement;
    while (current && !current.classList.contains(className)) {
        current = current.parentElement;
    }
    return current;
}

// استفاده
const parentWithClass = findParentWithClass(element, 'container');

کار با فرم‌ها

دسترسی به مقادیر فرم

// دریافت مقدار input
const nameInput = document.getElementById('name');
const name = nameInput.value;

// تنظیم مقدار
nameInput.value = 'نام جدید';

// کار با checkbox
const checkbox = document.getElementById('agree');
const isChecked = checkbox.checked;
checkbox.checked = true;

// کار با select
const select = document.getElementById('country');
const selectedValue = select.value;
const selectedText = select.options[select.selectedIndex].text;

اعتبارسنجی فرم

function validateForm() {
    const form = document.getElementById('myForm');
    const inputs = form.querySelectorAll('input[required]');
    let isValid = true;
    
    inputs.forEach(input => {
        if (input.value.trim() === '') {
            input.style.borderColor = 'red';
            isValid = false;
        } else {
            input.style.borderColor = '';
        }
    });
    
    return isValid;
}

// استفاده
if (validateForm()) {
    console.log('فرم معتبر است');
} else {
    console.log('لطفا فیلدهای ضروری را پر کنید');
}

بهترین شیوه‌ها

💡 نکات مهم:

  • کارایی: از querySelector به جای getElementById استفاده کنید
  • کش کردن: عناصر پرکاربرد را در متغیر ذخیره کنید
  • ایمنی: همیشه وجود عنصر را بررسی کنید
  • تمیزی: از innerHTML برای محتوای HTML استفاده کنید
  • دسترسی: ویژگی‌های accessibility را رعایت کنید

مثال بهینه

// کش کردن عناصر
const elements = {
    container: document.getElementById('container'),
    button: document.querySelector('.submit-btn'),
    inputs: document.querySelectorAll('input')
};

// تابع امن برای دستکاری DOM
function safeUpdateElement(selector, content) {
    const element = document.querySelector(selector);
    if (element) {
        element.textContent = content;
        return true;
    }
    console.warn(`عنصر با selector "${selector}" پیدا نشد`);
    return false;
}

// استفاده
safeUpdateElement('#status', 'بروزرسانی شد');

// تابع برای ایجاد عنصر با ویژگی‌ها
function createElement(tag, attributes = {}, content = '') {
    const element = document.createElement(tag);
    
    Object.entries(attributes).forEach(([key, value]) => {
        if (key === 'className') {
            element.className = value;
        } else {
            element.setAttribute(key, value);
        }
    });
    
    if (content) {
        element.textContent = content;
    }
    
    return element;
}

// استفاده
const newButton = createElement('button', {
    className: 'btn btn-primary',
    'data-action': 'submit',
    id: 'submitBtn'
}, 'ارسال');

آزمون درس ۱۶

سوال ۱: کدام متد برای انتخاب همه عناصر با کلاس خاص استفاده می‌شود؟

سوال ۲: تفاوت textContent و innerHTML چیست؟

سوال ۳: کدام متد برای حذف عنصر از DOM استفاده می‌شود؟