2012-02-01 37 views
6

Các mã sau đây [jsfiddle] ...Thẻ tự đóng/bỏ ghép tùy chỉnh trong HTML?

var div = document.createElement("div"); 
div.innerHTML = "<foo>This is a <bar /> test. <br> Another test.</foo>"; 
alert(div.innerHTML); 

... cho thấy cấu trúc này phân tích:

<foo>This is a <bar> test. <br> Another test.</bar></foo> 

tức là trình duyệt biết rằng <br> không có thẻ đóng nhưng vì <bar> là một thẻ vô danh với trình duyệt, nó giả định rằng nó cần một thẻ đóng.

Tôi biết rằng cú pháp /> (solidus) bị bỏ qua trong HTML5 và không hợp lệ trong HTML4, nhưng dù sao thì muốn dạy bằng cách nào đó trình duyệt <bar> không cần thẻ kết thúc và tôi có thể bỏ qua nó. Có thể không?

Có, tôi đang cố gắng (tạm thời) lạm dụng mã HTML cho thẻ tùy chỉnh và tôi có lý do cụ thể để làm điều đó. Sau khi tất cả, các trình duyệt nên bỏ qua các thẻ không xác định và xử lý chúng giống như các thẻ nội tuyến không được đặt trước, vì vậy tôi không nên phá vỡ bất kỳ điều gì lâu dài để đảm bảo tên thẻ sẽ không bao giờ được sử dụng trong các tiêu chuẩn HTML thực.

+1

Bạn được tự do downvote, nhưng hãy thêm một bình luận giải thích lý do ... –

Trả lời

5

Bạn sẽ phải sử dụng Object.defineProperty trên HTMLElement.prototype để ghi đè bộ lọc bên trongHTML và getter bằng cách thực hiện innerHTML của riêng bạn xử lý các phần tử bạn muốn là void. Hãy xem here để biết cách bên trong HTML và trình phân tích cú pháp HTML được triển khai theo mặc định.

Lưu ý rằng Firefox không thừa kế khi nói đến việc xác định nội dung trên HTMLElement.prototype nơi nó lọc xuống HTMLDivElement chẳng hạn. Mọi thứ sẽ hoạt động tốt trong Opera.

Nói cách khác, các phần tử nào bị vô hiệu phụ thuộc vào trình phân tích cú pháp HTML. Trình phân tích cú pháp theo sau this list và innerHTML sử dụng cùng một quy tắc chủ yếu.

Vì vậy, nói cách khác, trừ khi bạn muốn tạo triển khai innerHTML của riêng bạn trong JS, có thể bạn nên quên điều này.

Bạn có thể sử dụng live DOM viewer để hiển thị cho người khác cách phân tích đánh dấu nhất định. Sau đó, bạn có thể sẽ nhận thấy rằng các thẻ kết thúc giống nhau sẽ đóng hoàn toàn phần tử mở.

Tôi có một số mã getHTML bên trong đã lỗi thời (không phải setter) mã here sử dụng danh sách yếu tố void. Điều đó có thể cung cấp cho bạn một số ý tưởng. Tuy nhiên, viết một triển khai setter có thể khó khăn hơn. Mặt khác, nếu bạn sử dụng createElement() và appendChild() vv thay vì innerHTML, bạn không cần phải lo lắng về điều này và phần tử getHTML nội bộ gốc sẽ xuất ra các phần tử không xác định bằng các thẻ kết thúc.

Lưu ý mặc dù, bạn có thể điều trị các yếu tố chưa biết như xml và sử dụng XMLSerializer() và DOMParser() để thực hiện điều:

var x = document.createElement("test"); 
var serializer = new XMLSerializer(); 
alert(serializer.serializeToString(x)); 
var parser = new DOMParser(); 
var doc = parser.parseFromString("<test/>", "application/xml"); 
var div = document.createElement("div"); 
div.appendChild(document.importNode(doc.documentElement, true)); 
alert(serializer.serializeToString(div)); 

Đó không phải là chính xác những gì bạn muốn, nhưng một cái gì đó bạn có thể chơi với. (Kiểm tra trong Opera thay vì Firefox để thấy sự khác biệt với các thuộc tính xmlns. Cũng lưu ý rằng Chrome không hoạt động như Opera và Firefox.)

+0

Cảm ơn tất cả các tài liệu tham khảo hữu ích.Tôi đang sử dụng innerHTML vì hai lý do: thứ nhất, bởi vì nó là một trình phân tích cú pháp khá nhanh và khoan dung. Thứ hai, vì mục tiêu của tôi không dựa vào innerHTML mà còn cho phép sử dụng một cây con DOM hiện có. Điều này ngụ ý rằng bản thân trình duyệt phải chấp nhận các thẻ void mới, nếu điều đó có thể xảy ra. --- Là một lưu ý phụ, tôi tự hỏi làm cách nào để thêm các thẻ ** void ** mới vào, ví dụ, tiêu chuẩn HTML6 + vì chúng dường như sẽ làm lẫn lộn tất cả các trình phân tích cú pháp HTML5 ... –

+0

@UdoG Đã thêm một chút gì đó bạn có thể chơi cùng. – Shadow2531

Các vấn đề liên quan