jquery
Kiến thức

Chương 5 – Sửa đổi DOM

Gói phần tử

Phương thức dùng để gói một phần tử này bên trong phần tử khác có tên là .wrap(). Bởi vì chúng ta muốn mỗi một $(this) sẽ được gói trong cặp thẻ <lli><l/li>, chúng ta có thể hoàn thiện mã cho phần ghi chú như sau:

$(document).ready(function() { 
$('<ol id="notes"></ol>').insertAfter('div.chapter'); 
$('span.footnote').each(function(index) { 
$(this) 
.before( 
['<a href="#foot-note-', 
index+1, 
'" id="context-', 
index+1, 
'" class="context">', 
'<sup>' + (index+1) + '</sup>', 
'</a>' 
].join('') 
) 
.appendTo('#notes') 
.append( '&nbsp;(<a href="#context-' + (index+1) + 
'">context</a>)' ) 
.wrap('<li id="foot-note-' + (index+1) + 
'"></li>'); 
});
});

Bây giờ mỗi phần tử <li> đều có một id bằng với href của nó. Cuối cùng chúng ta đã có một danh sách các đoạn ghi chú được đánh dấu và liên kết với nhau.

jquery

Xem Demo Online – Example 6

Tất nhiên, số thứ tự có thể được chèn vào trước từng dòng ghi chú như cách mà chúng được chèn trong đoạn văn. Tuy nhiên bạn có thể thấy rất “khoái chí” khi chúng ta có những đoạn mã hợp chuẩn được tự động tạo ra bởi JavaScript.

Sao chép phần tử

Từ đầu chương cho tới giờ chúng ta đã chèn phần tử được tạo ra, di chuyển nó từ vị trí này sang vị trí khác của tài liệu, gói phần tử đã có bằng một phần tử mới. Nhưng cũng có khi chúng ta muốn sao chép một phần tử nào đó. Ví dụ khi bạn có một thanh di chuyển ở trên cùng của trang, bạn muốn copy nó và chèn nó xuống phần footer. Thực ra nếu bạn muốn copy lại phần nào của trang để tăng tính thẩm mỹ của nó thì bạn nên sử dụng mã để cho nó làm tự động cho mình. Mà suy cho cùng thì tại sao chúng ta phải mất thời gian và công sức để viết lại một đoạn mã y chang làm gì? Tại sao không để jQuery làm giúp vừa lẹ mà lại vừa tránh sai sót.

Để sao chép phần tử, phương thức .clone() là tất cả những gì chúng ta cần. Phương thức này sẽ tạo ra một bản sao của phần tử mà chúng ta chọn để dùng sau này. Cũng như những phương thức tạo ra các phần tử mới mà chúng ta đã học ở trên, phương thức này cũng không tạo ra thay đổi gì cho đến khi chúng ta sử dụng một trong những phương thức chèn. Cũng giống như khi bạn copy một đoạn văn trong Microsoft Word, khi bạn vừa bôi đen và chọn copy. Thì MS Word sẽ lưu đoạn văn đó trong bộ nhớ của máy, nhưng trên tài liệu chưa có gì xuất hiện. Cho đến khi bạn chọn Paste thì đoạn văn copy mới được hiển thị. Phương thức .clone() cũng hoạt động theo nguyên lý đó.

Đoạn mã dưới đây sẽ tạo ra một bản sao của đoạn văn nằm trong thẻ <div class=’chapter’>.

$('div.chapter p:eq(0)').clone();

Như đã nói ở trên, khi bạn cho chạy đoạn code trên sẽ không có gì xảy ra hết. Bởi vì jQuery mới chỉ copy đoạn văn đó thôi chứ nó chưa làm gì với nó cả.

Để cho đoạn văn chúng ta vừa copy xuất hiện, chúng ta sẽ cho nó xuất hiện ở trên thẻ <div class=’chapter’>

$('div.chapter p:eq(0)').clone().insertBefore('div.chapter');

Bây giờ nếu cho chạy đoạn mã trên, bạn sẽ thấy đoạn văn đầu được xuất hiện 2 lần và bởi vì nó không còn nằm trong thẻ <div class=’chapter’> nữa cho nên những style nào bạn áp dụng trong CSS sẽ không có tác dụng với nó. Ở đây bạn thấy rõ nhất là nó rộng hơn những đoạn văn còn lại.

Sao chép kèm sự kiện

Mặc định của phương thức .clone() là không sao chép bất cứ sự kiện nào hoặc “họ hàng nội ngoại” của đối tượng được chọn. Nhưng nó cũng có thể lấy vào một tham số Boolean, mà khi giá trị này là true, nó sẽ sao chép cả sự kiện đi kèm: .clone(true). Như vậy chúng ta đỡ phải mất công gán lại sự kiện cho nó trong trường hợp chúng ta muốn nó đi kèm.

Sao chép cho phần trích dẫn

Khi bạn đọc báo giấy, đôi khi bạn thấy có phần khung in nhỏ, trong đó có những mẩu trích dẫn những đoạn quan trọng để gây sự chú ý. Chúng ta có thể làm được việc này bằng cách sử dụng phương thức .clone(). Hãy xem lại đoạn mã HTML của đoạn văn thứ 3 của chúng ta.

<p> 
<span class="pull-quote">It is a Law of Nature 
<span class="drop">with us</span> that a male child shall 
have <strong>one more side</strong> than his father</span>
so that each generation shall rise (as a rule) one step in 
the scale of development and nobility. Thus the son of a 
Square is a Pentagon; the son of a Pentagon, a Hexagon; and 
so on.
</p>

Đoạn văn bắt đầu bằng một thẻ <span class=’pull-quote’>. Đây sẽ là class chúng ta sẽ dùng để sao chép. Một khi đoạn văn nằm trong thẻ <span> đó được copy, chúng ta sẽ dán nó vào một nơi khác và chúng ta cũng cần chỉnh sửa lại style cho nó bắt mắt hơn.

Chúng ta sẽ gán một class là ‘pulled’ cho thẻ <span> vừa được copy và khai báo những thuộc tính sau trong CSS

.pulled { 
background: #e5e5e5; 
position: absolute; 
width: 145px; 
top: -20px; 
right: -180px; 
padding: 12px 5px 12px 10px; 
font: italic 1.4em "Times New Roman", Times, serif;
}

Đoạn trích dẫn có màu nền xanh nhạt, một ít padding và font khác. Chúng ta cũng sử dụng absolute position để định vị cho thành phần mới này.

Bây giờ chúng ta sẽ quay lại phần jQuery. Chúng ta sẽ bắt đầu với biểu thức bộ trọng cho tất cả các thẻ <span class=’pull-quote’>, sau đó chúng ta sẽ gán vào phương thức .each() để chạy qua từng phần tử một.

$(document).ready(function() { 
$('span.pull-quote').each(function(index) { 
//... 
});
});
Tiếp theo chúng ta tìm đoạn văn “cha mẹ” của từng đoạn trích dẫn và áp dụng thuộc tính CSS
$(document).ready(function() { 
$('span.pull-quote').each(function(index) { 
var $parentParagraph = $(this).parent('p'); 
$parentParagraph.css('position', 'relative'); 
});
});

Một lần nữa, chúng ta lưu lại bộ chọn mà chúng ta sẽ sử dụng hơn một lần vào một biến để giúp cho mã của chúng ta hoạt động hiệu quả hơn và cũng dễ đọc hơn.

Bây giờ sau khi đã thiết lập xong hai giá trị định vị quan trọng của CSS là relative cho đoạn văn chứa phần trích dẫn và absolute cho đoạn trích dẫn. Tiếp theo chúng ta có thể copy từng thẻ <span> và thêm class là pulled cho từng bản sao, và cuối cùng là chèn nó vào phần bắt đầu của đoạn văn bản.

Lưu ý: nếu bạn chưa hiểu kỹ khái niệm này, bạn có thể xem video về Absolute Position trong CSS

$(document).ready(function() { 
$('span.pull-quote').each(function(index) { 
var $parentParagraph = $(this).parent('p'); 
$parentParagraph.css('position', 'relative'); 
$(this).clone() 
.addClass('pulled') 
.prependTo($parentParagraph); 
});
});

Bởi vì chúng ta sử dụng absolute position cho đoạn trích dẫn, cho nên nó sẽ định vị theo đoạn văn bản chứa nó. Dưới đây là hình mà chúng ta có được đến bước này.

Về cơ bản thì đoạn trích dẫn nhìn cũng tạm ổn rồi, nhưng thường thì phần trích dẫn không có cùng định dạng văn bản như là đoạn văn được copy. Ở đây đoạn chích dẫn của chúng ta có một vài chữ được tô đậm. Điều chúng ta muốn là đoạn văn sau khi được copy sẽ loại bỏ hết những thẻ <strong>, <em> và <a href> hoặc bất cứ thẻ inline nào đi. Hơn nữa chúng ta cũng muốn sau khi copy thì cũng có thể sửa đổi nó chút chút như là xoá đi vài từ và thay thế nó bằng dấu ba chấm …. Quay lại đoạn mã HTML, bạn sẽ thấy có một vài từ được đặt nằm trong cặp thẻ <span class=’drop’> không đơn giản </span>.

Chúng ta sẽ làm dấu 3 chấm trước sau đó sẽ loại bỏ hết các thuộc tính HTML đi và chỉ giữ lại phiên bản chữ không.

$(document).ready(function() { 
$('span.pull-quote').each(function(index) { 
var $parentParagraph = $(this).parent('p'); 
$parentParagraph.css('position', 'relative'); 
var $clonedCopy = $(this).clone(); 
$clonedCopy 
.addClass('pulled') 
.find('span.drop') 
.html('&hellip;') 
.end() 
.prependTo($parentParagraph); 
var clonedText = $clonedCopy.text(); 
$clonedCopy.html(clonedText); 
});
});

Chúng ta bắt đầu quá trình sao chép bằng cách lưu bản sao vào một biến. Lần này biến được tạo ra là cần thiết bởi vì chúng ta không thể làm việc hoàn toàn với nó trong cùng một dòng lệnh. Bạn cũng đã thấy là sau khi chúng ta tìm hết những thẻ <span class=’drop’> và thay thế nó với dấu ba chấm, chúng ta sử dụng một phương thức .end(). Phương thức này nói cho jQuery biết, chúng ta muốn quay lại một trước bước. Trong trường hợp này chúng ta muốn quay lại đến bước .find(‘span.drop’). Như thế chúng ta sẽ chèn cả đoạn copy chứ không phải chỉ là dấu ba chấm vào phần đầu của đoạn văn.

Cuối cùng chúng ta tạo thêm một biến nữa là clonedText, biến này sẽ chứa phiên bản chữ không của đoạn văn chúng ta cần copy. Sau đó chúng ta sử dụng phiên bản chữ không có định dạng này để thay thế cho phiên bản HTML. Bây giờ đoạn trích dẫn sẽ như hình

jquery

Ở hình trên tôi đã thêm một đoạn <span class=’pull-quote’> vào để xem mã của chúng ta có thể tự động tạo ra một đoạn trích dẫn nữa không.

Bo tròn góc cho đoạn trích

Bây giờ đoạn trích dẫn đã hoạt động như mình muốn là những phần tử con bị loại bỏ, dấu 3 chấm được thêm vào để thay cho chữ. Nếu bây giờ chúng ta muốn cho đoạn trích dẫn được bo tròn góc thì sao. Chúng ta có thể tạo ra một thẻ <div> bao quanh lấy đoạn trích.

$(document).ready(function() { 
$('span.pull-quote').each(function(index) { 
var $parentParagraph = $(this).parent('p'); 
$parentParagraph.css('position', 'relative'); 
var $clonedCopy = $(this).clone(); 
$clonedCopy 
.addClass('pulled') 
.find('span.drop') 
.html('&hellip;') 
.end() 
.prependTo($parentParagraph) 
.wrap('<div class="pulled-wrapper"></div>'); 
var clonedText = $clonedCopy.text(); 
$clonedCopy.html(clonedText); 
});
});

Chúng ta cũng cần phải chỉnh sửa mã CSS để có thể tạo ra hiệu ứng bo tròn góc.

.pulled-wrapper { 
background: url(top-bg.png) no-repeat left top; 
position: absolute; 
width: 160px; 
right: -180px; 
padding-top: 18px;
}
.pulled { 
background: url(bottom-bg.png) no-repeat left bottom; 
position: relative; 
display: block; 
width: 140px; 
padding: 0 10px 24px 10px; 
font: italic 1.4em "Times New Roman", Times, serif;
}
jquery

Xem Demo Online – Example 7

Tóm lược các phương thức sửa đổi DOM

Sự khác biệt giữa những phương thức sửa đổi DOM mà jQuery cung cấp cho chúng ta phụ thuộc vào nhiệm vụ và vị trí của nó. Phần này sẽ tóm lược cho bạn dễ nhớ phương thức nào nên được sử dụng để làm gì và khi nào thì nên sử dụng chúng

1.Để tạo một phần tử mới từ HTML, sử dụng hàm $().
2.Để chèn một hoặc nhiều phần tử vào trong một phần tử khác sử dụng
.append()
.appendTo()
.prepend()
.prependTo()
3.Để chèn một phần tử mới vào bên cạnh một phần tử khác sử dụng
.after()
.insertAfter()
.before()
.insertBefore()
4.Để chèn một phần tử mới xung quanh một phần tử khác, sử dung
.wrap()
.wrapAll()
.wrapInner()
5.Để thay thế một phần tử này với phần tử khác hoặc chữ sử dụng
.html()
.text()
.replaceAll()
.replaceWith()
6.Để loại bỏ một phần tử nằm trong một phần tử khác dùng
.empty()
7.Để loại bỏ một phần tử và con cái của nó trong một tài liệu mà không thực sự xoá nó dùng
.remove()

Tóm tắt

Trong chương này chúng ta đã tạo, sao chép, tái kết hợp và làm đẹp cho phần nội dung sử dụng phương pháp sửa đổi DOM của jQuery. Chúng ta đã áp dụng những phương thức này cho một trang web để biến những đoạn văn bình thường thành phần chú thích tự động, phần trích dẫn, đường liên kết v.v..

Phần tutorial của cuốn sách cũng sắp hết, nhưng trước khi chúng ta học thêm những ví dụ phức tạp hơn và mở rộng hơn. Chúng ta hãy dành chút thời gian để nghiên cứu phương thức AJAX của jQuery. Trong chương kế tiếp, chúng ta hãy dạo một vòng lên server nhờ “phi thuyền” AJAX.

Download định dạng pdf

Bạn có thể download định dạng .pdf của chương này ở link này

Related posts

WordPress – Custom Post Type

admin

PHP Căn Bản – Bài 7 – Phần 1

admin

Ajax-Jquery vs JavaScript

admin

Leave a Comment