jquery
Kiến thức

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

Di chuyển các phần tử

Với ví dụ về đường liên kết back to top ở trên, chúng ta đã tạo ra những phần tử mới và chèn chúng vào trang. Nhưng chúng ta cũng có thể di chuyển một phần tử từ nơi này qua nơi khác. Một ứng dụng thực tế của cách chèn này là dạng tự động hoá cách chèn phần ghi chú ở cuối trang. Một phần chú thích đã có trong đoạn văn mẫu và chúng ta sẽ sử dụng nó trong ví dụ này. Chúng ta cũng đã tạo ra một số phần ghi chú khác cho ví dụ này.

<p><span class="pull-quote">
        Có những thuộc tính <span class="drop">không đơn giản</span> để sửa đổi nếu không có sự trợ giúp của 
        jQuery. Hơn nữa, <strong>jQuery</strong> cho phép chúng ta</span> sửa đổi nhiều thuộc tính cùng một lúc,
         tương tự như cách mà chúng ta làm việc với nhiều thuộc tính CSS khi sử dụng 
         phương thức .css() ở chương 4. Ở ví dụ này, chúng ta có thể dễ dàng thiết lập 
         id, rel và thuộc tính title cho đường liên kết cùng một lúc. Dưới đây là mã 
         HTML
         </p>
         
         <p>
         Pellentesque habitant morbi tristique senectus et netus et malesuada fames 
         ac turpis egestas. <span class="footnote">Vestibulum tortor quam, feugiat vitae, ultricies eget, 
         tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. 
         Aenean ultricies mi vitae est</span>. Mauris placerat eleifend leo. Quisque 
         sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, 
         condimentum sed, commodo vitae, ornare sit amet, wisi.
         </p>
         
         <p>
         Pellentesque habitant morbi tristique senectus et netus et malesuada fames 
         ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, 
         tempor sit amet, ante. <span class="footnote">Donec eu libero sit amet quam egestas semper. 
         Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque 
         sit amet est et sapien ullamcorper pharetra.</span> Vestibulum erat wisi, 
         condimentum sed, commodo vitae, ornare sit amet, wisi.
         </p>
         
         <p>
         Pellentesque habitant morbi tristique senectus et netus et malesuada fames 
         ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, 
         tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. 
         Aenean ultricies mi vitae est. <span class="footnote">Mauris placerat eleifend leo. Quisque 
         sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, 
         condimentum sed, commodo vitae, ornare sit amet, wisi.</span>
         </p>

Mỗi một đoạn văn này có một đoạn ghi chú được gói trong thẻ <span class=’footnote’></span>. Khi viết mã HTML như thế này, chúng ta đã bảo tồn được ngữ cảnh của ghi chú. Sau đó trong CSS stylesheet, chúng ta cho nó in nghiêng và được hình dưới đây.

Bây giờ chúng ta có thể lấy phần ghi chú và chèn chúng vào giữa hai thẻ <div class=’chapter’><div id=’footer’>. Bạn cũng nên biết rằng kể cả trong trường hợp của vòng lặp ẩn, thứ tự chèn đã được định trước, bắt đầu từ trên cây DOM đi xuống dưới. Bởi vì chúng ta cũng cần bảo tồn thứ tự của phần ghi chú ở vị trí mới của nó trên trang, cho nên chúng ta sẽ dùng .insertBefore(‘#footer’).

Làm như vậy sẽ chèn từng phần ghi chú ngay trên thẻ <div id=’footer’>. Do đó ghi chú thứ nhất sẽ được đặt nằm giữa <div class=’chapter’> và <div id=’footer’>, ghi chú thứ 2 sẽ được nằm giữa ghi chú thứ nhất và thẻ <div id=’footer’>, v.v.. Mặt khác, nếu chúng ta sử dụng .insertAfter(‘div.chapter’), thì thứ tự sẽ bị đảo lộn. Cho nên mã của chúng ta sẽ như sau

$(document).ready(function() { 
$('span.footnote').insertBefore('#footer');
});

Ở đây chúng ta lại có thêm một vấn đề nữa. Đó là các dòng ghi chú được nằm trong thẻ <span>, mà bản thân thẻ <span> có display: inline theo mặc định, do vậy các dòng ghi chú nối liền nhau mà không xuống dòng.

Chúng ta sẽ chỉnh sửa CSS để giải quyết vấn đề này, chúng ta sẽ làm cho những phần tử <span> trở thành block-level, nhưng chỉ áp dụng với những thẻ nằm trong &lt;div class=’chapter’>

span.footnote { 
font-style: italic; 
font-family: "Times New Roman", Times, serif; 
display: block; 
margin: 1em 0;
}
.chapter span.footnote { 
display: inline;
}

Bây giờ thì phần ghi chú của chúng ta đã xuống dòng.

jquery

Xem Demo Online – Example 4

Ít ra thì phần ghi chú của chúng ta nhìn cũng đã tạm được rồi, nhưng còn nhiều việc chúng ta có thể làm để cải thiện nó. Một số điểm cần làm như sau:
1.Đánh dấu vị trí trong tài liệu nơi mà ghi chú được sử dụng
2.Đánh số cho từng vị trí và cung cấp một số phù hợp với bản thân từng dòng ghi chú.
3.Tạo đường liên kết giữa vị trí văn bản đến điểm ghi chú, và từ điểm ghi chú ngược lại đoạn văn bản.
Những bước này có thể làm được nhờ phương thức .each(), nhưng trước hết chúng ta phải tạo ra một nơi chứa những dòng ghi chú ở dưới cùng của trang.

$(document).ready(function() { 
$('<ol id="notes"></ol>').insertAfter('div.chapter');
});

Chúng ta sử dụng một danh sách đánh số <ol id=’notes’> </ol> cho phần ghi chú, bởi vì mình muốn chúng tự động được đánh số thứ tự. Chúng ta đã cho danh sách này một id=’notes’ và chèn nó vào sau thẻ <div class=’chapter’>.

Đánh dấu, đánh số và liên kết văn bản

Bây giờ chúng ta đã có thể đánh dấu và đánh số vị trí mà phần ghi chú được trích dẫn.

$(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('') 
) 
});
});

Ở đây chúng ta sử dụng bộ chọn giống với bộ chọn ở ví dụ trước, nhưng khác cái là chúng ta gắn phương thức .each() cho nó. Ở trong .each() chúng ta bắt đầu bằng $(this), nó là đại diện của từng dòng ghi chú liên tiếp nhau, và chúng ta gắn phương thức .method() cho nó.

Kết quả của cả đoạn mã “loằng ngoằng” nằm trong dấu ngoặc đơn của phương thức .before() sẽ là một đường siêu liên kết. Nó sẽ được chèn vào trước từng thẻ <span> của phần ghi chú. Dưới đây là mã HTML của một trong những dòng ghi chú khi nó được chèn vào DOM.

<a href="#foot-note-1" id="context-1" 
class="context"><sup>1</sup></a>

Cú pháp nhìn có vẻ khá phức tạp, nên chúng ta dành vài phút để tìm hiểu xem nó như thế nào. Bên trong dấu ngoặc đơn của phương thức .before(), chúng ta bắt đầu với một cặp ngoặc vuông -[ ] – nó chính là đại diện của mảng trực kiện (array literal). Mỗi phần tử nằm trong array sẽ có một dấu phảy theo sau (trừ phần tử cuối cùng, nếu không mã sẽ không chạy). Để cho dễ đọc hơn, chúng ta đã viết mỗi lệnh trên một dòng. Sau khi mảng đã lập xong, chúng ta chuyển nó lại thành dạng chuỗi bằng cách sử dụng phương thức của JavaScript là .join(). Phương thức này lấy vào một chuỗi rỗng làm đối số, chuỗi rỗng được biểu thị bởi một cặp dấu nháy (‘ ‘), bởi vì chúng ta không muốn bất cứ thứ gì xuất hiện giữa các phần tử mảng khi nó được xuất ra dạng HTML.

Lưu ý bạn đến phần index+1 trên đoạn mã trên. Bởi vì JavaScript đánh số bắt đầu từ 0, do vậy để thuộc tích href có giá trị là #footnote-1, thì chúng ta phải công 1 đơn vị cho nó. Thuộc tính id là #context-1 và tên của đường link sẽ là 1. Thuộc tính href đặc biệt quan trọng, bởi vì nó phải tuyệt đối phù hợp với thuộc tính id của phần ghi chú (tất nhiên là không gồm dấu #).

Cách thứ 2 chúng ta cũng có thể sử dụng chuỗi nối thay vì dùng mảng ghép:

.before('<a href="#foot-note-' + (index+1) + 
'" id="context-' + (index+1) + 
'" class="context"><sup>' + 
(index+1) + '</sup></a>');

Nhưng trong trường hợp này, cách sử dụng mảng có vẻ dễ quản lý hơn.

Lưu ý: Đã có nhiều tài liệu nói về sự khác nhau về mặt hiệu năng làm việc giữa mảng ghép và chuỗi nối. Nếu bạn còn phân vân, bạn có thể đọc tài liệu sau http://www.sitepen.com/blog/2008/05/09/string-performance-an-analysis/

Tuy nhiên, trong hầu hết các trường hợp, những khác biệt này là không đáng kể. Nếu hiệu năng làm việc của đoạn mã là điều cần quan tâm thì còn nhiều yếu tố khác có tầm ảnh hưởng còn lớn hơn như là cách lưu bộ chọn mà chúng ta đã bàn.

jquery

Xem Demo Online – example 5

Gắn phần ghi chú

Bước kế tiếp là di chuyển phần tử <span class=’footnote’> như chúng ta đã làm. Tuy nhiên, lần này chúng ta sẽ đặt nó vào trong thẻ <ol id=’note’> vừa mới được tạo. Chúng ta sẽ sử dụng .appendTo(), nhưng cũng để giữ đúng thứ tự, những dòng ghi chú kế tiếp sẽ được chèn vào cuối của hàng.

$(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') 
});
}); 

Bạn cũng nên nhớ rằng .appendTo() đang được gắn với $(this), cho nên nói theo ngôn ngữ của jQuery thì là “gắn phần ghi chú span vào phần tử với id là ‘notes’.

Đối với mỗi dòng ghi chú mà chúng ta vừa di chuyển, chúng ta sẽ gắn cho nó một đường liên kết khác. Đường liên kết này sẽ quay lại số thứ tự nằm trong văn bản.

$(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>)' ); 
});
});

Chú ý đến thuộc tính href quay ngược lại id phù hợp với chỗ đánh dấu trước. Dưới đây bạn sẽ thấy phần ghi chú đã được gắn đường liên kết.

jquery

Tuy nhiên phần ghi chú vẫn chưa có số thứ tự, mặc dù chúng đã được đặt trong thẻ <ol>, là bởi vì mỗi một dòng sẽ phải được đặt nằm giữa thẻ <li>.

Related posts

Plug n Play #02: Theme WordPress miễn phí cực chất tháng 7

admin

Hướng dẫn sử dụng và tạo plugin Testimonials hiển thị ý kiến khách hàng

admin

Fonts for web: Web fonts

admin

Leave a Comment