2010-02-14 7 views
5

Tôi đang cố gắng phát triển một cách đơn giản để tạo mẫu bằng JavaScript. Ý tưởng cơ bản là tôi đã có HTML trong một trang đại diện cho giao diện người dùng của một đối tượng trong JavaScript và các biến trong HTML được thay thế bằng các thuộc tính của đối tượng JavaScript. Hãy nghĩ về nó như kỹ thuật để gắn các đối tượng JavaScript vào các bài thuyết trình HTML.Cải tiến kỹ thuật tạo mẫu JavaScript đơn giản

Mọi phê bình? Tôi có nên sử dụng các mảnh tài liệu bằng cách nào đó không? Tôi về cơ bản đang tìm kiếm một đánh giá mã trên này. Tôi đánh giá cao bất kỳ phản hồi nào. (Lưu ý rằng điều này sẽ là khung độc lập.) Dưới đây là một exmaple làm việc.

<html> 
<body> 

    <!-- where templates will be injected into --> 
    <div id="thumbContainer"></div> 

    <!-- template used for thumbnails --> 
    <div id="thumbTemplate" style="display:none"> 
     <div class="thumb"> 
      <div>${caption}</div> 
      <div>${image}</div> 
     </div> 
    </div> 

</body> 

<script type="text/javascript"> 
(function() { 

    // Cache the templates' markup in case that template is used again 

    var cache = []; 

    // Magic 

    document.templatized = function(templateId, properties) { 

     // Get the template from cache or get template and add to cache 

     var template = cache[templateId] || (function() { 
      cache[templateId] = document.getElementById(templateId).innerHTML; 
      return cache[templateId]; 
     })(); 

     // Create the DOM elements that represent the markup 

     var shell = document.createElement('div'); 

     shell.innerHTML = template.replace(/\$\{(\w+)\}/g, function(match, key){ 
      return properties[key] || match; 
     }); 

     // Return those DOM elements 

     return shell.children[0].cloneNode(true); 
    }; 
})(); 

// Create DOM elements with values bound to thumbnail object 

var thumb = document.templatized('thumbTemplate', { 
    caption: 'Summer', 
    image: (function() { 
      // More complicated logic that requires conditions here... 
     return '<img src="test.png" />'; 
    })() 
}); 

// Display on page by inserting into DOM 

document.getElementById('thumbContainer').appendChild(thumb); 
</script> 
+0

+1 cho // magic – cherouvim

+0

Haha, cảm ơn! :) – JamesBrownIsDead

Trả lời

2

Mã này gọn gàng.

Tôi muốn có mẫu trong nhận xét html nên 1) nó không được hiển thị (không cần hiển thị: không hack) và 2) Tôi có thể có nội dung không xác thực, chẳng hạn trực tiếp là <tr>.

Ngoài ra, tôi sẽ xóa bản dựng 'div' được mã hóa cứng để tôi có thể hỗ trợ các đoạn mẫu bắt đầu bằng bất kỳ phần tử html nào.

Sau đó, tôi sẽ thêm điều hướng biểu đồ (ví dụ: $ {foo.bar}), phép lặp và câu lệnh if.

2

+1 cherouvim: bạn đang sử dụng mẫu làm văn bản, vì vậy hãy giữ mẫu dưới dạng văn bản. Bạn có thể chuyển nó vào kịch bản của bạn dưới dạng nhận xét hoặc bạn có thể chuyển nó thành chuỗi được mã hóa JSON, nhưng việc sử dụng đánh dấu cho nó có khả năng gây nguy hiểm.

Ví dụ:

<form method="${mymethod}"><table> 
    <tr><td> 
     <${mylisttype}> 
      <li> 
       <input name="foo" value="${myvalue}"> 
      </li> 
     </${mylisttype}> 
    </td></tr> 
    ${extrarow} 
</table></form> 

minh họa một số điều bạn có thể không đáng tin cậy làm bằng ngôn ngữ khuôn mẫu của bạn do trình duyệt 'sửa chữa' đánh dấu và thay đổi trở innerHTML lại: các form chưa bị biến đổi để method="get" (hoặc, trong IE, bỏ qua FSR); trừ khi bạn đang ở chế độ XML, sẽ có thêm một phần tử <tbody>; phần tử có thể thay đổi sẽ không hoạt động; văn bản ${extrarow} không hợp lệ trực tiếp bên trong bảng; input.value có thể bị đột biến khi tải trang vì các trình duyệt cố gắng đặt lại các giá trị trường biểu mẫu và IE phản ánh không chính xác các thay đổi giá trị trường dưới dạng thuộc tính/innerHTML. Ngoài ra, tôi đặc biệt khuyên bạn nên thêm tính năng mã hóa HTML (thay thế & bằng &amp;, < với &lt; và bất kỳ dấu phân cách giá trị thuộc tính nào có tham chiếu tương tự). Kinh nghiệm với ngôn ngữ templating đã cho thấy nó phổ biến hơn nhiều để muốn chèn một chuỗi văn bản vào tài liệu hơn là một đoạn đánh dấu. Khi bạn thực hiện:

Hello, ${name}! 

mà không cần áp dụng để thoát khỏi biến name, bạn đang mở ứng dụng của mình tới các cuộc tấn công cross-site-scripting. Ngôn ngữ lập trình hiện đại tránh điều này bằng cách áp dụng mã hóa HTML theo mặc định, bởi vì các lập trình viên quá lười để thực hiện thủ công (nếu họ thậm chí hiểu các vấn đề liên quan). Đây là lý do tại sao phần lớn các ứng dụng PHP dễ bị tấn công XSS.

Không mang lại cùng một vấn đề cho phía máy khách; làm cho nó thoát theo mặc định, cung cấp một cờ để nói rằng bạn không muốn thoát cho (thường là tương đối ít) trường hợp mà bạn muốn chèn đánh dấu thô:

<div>${caption}</div> 
<div>${image|markup}</div> 
+1

tính năng mã hóa html sẽ là tuyệt vời – cherouvim

1

Thay vì có nó trong một nhận xét HTML bạn có thể đặt nó vào các thẻ, ví dụ:

<script type="text/html" id="mytemplate"> 
    ... template here ... 
</script> 

Vẻ đẹp ở đây là tất cả các trình duyệt và tất cả các robot được viết đúng cách sẽ không hiểu cách diễn giải chúng; và bạn có thể dễ dàng truy cập nội dung thông qua ID (như nếu đó là div).

+0

Đây là cách một số plugin CSS templating hoạt động cũng như đề xuất templating của Microsoft. http://wiki.github.com/nje/jquery/jquery-templates-proposal – R0MANARMY