2009-02-26 28 views
7

Tôi đã nấu một mẫu để tạo và mở rộng các phần tử html bằng nguyên mẫu của chúng. Điều này hoạt động giống như một sự quyến rũ trong các trình duyệt không có nghĩa là. Mã ví dụ có thể được tìm thấy @jsbin (xem nguồn trang)Có thực sự không có cách nào để lộ nguyên mẫu của một phần tử html trong IE (<8)?

Ưu điểm của mẫu này phải là tốc độ (các phương pháp nằm trong chuỗi nguyên mẫu, vì vậy chúng được tham chiếu một lần). Bạn đoán đúng: IE không đi. Trong IE < 8 nguyên mẫu của các phần tử html bị ẩn/không thể truy cập được, vì vậy đối với mọi phần tử bạn tạo, bạn phải tham khảo các phương thức không chuẩn một lần nữa (để lại cho bạn nhiều con trỏ nếu bạn sử dụng mô hình mạnh). Tôi đã tìm kiếm trên web các giải pháp, nhưng chỉ tìm thấy cách giải quyết phức tạp. Có thực sự là không có cách nào để truy cập nguyên mẫu HTML trong IE không?

+0

là nguyên mẫu của các yếu tố html có sẵn trong IE8? Nếu có, truy cập như thế nào? – Helephant

+0

Đó là, theo như tôi hiểu. Và nó được truy cập thông qua nguyên mẫu (như document.getElementById ('someelement'). Prototype). Trong thời gian đó, tôi đã viết một trình bao bọc DOM để có thể sử dụng javascript bị rò rỉ miễn phí. – KooiInc

+0

@Helephant Có, nó có thể truy cập. Bạn có thể truy cập, ví dụ 'Element.prototype' và thêm phương thức vào nó. Điều này được đảm bảo bởi phiên bản mới nhất của [Tiêu chuẩn sống DOM] (https://dom.spec.whatwg.org/), xác định những thứ như 'Element' là [WebIDL] (http://www.w3.org/TR/WebIDL) giao diện, mang theo nó ngụ ý rõ ràng rằng họ nên có thể truy cập trong phạm vi toàn cầu và nguyên mẫu của họ nên được sửa đổi. –

Trả lời

12

Không, cũng không bảo đảm bạn có thể fiddle với các nguyên mẫu đối tượng DOM trong JavaScript nói chung. Các đối tượng DOM không phải là một phần của đặc tả ECMAScript; họ có thể không (và theo truyền thống nói không phải là) các đối tượng JavaScript nguyên gốc ở tất cả, trong bất kỳ trình duyệt nào.

Đây là lý do tại sao các khung có xu hướng có các lớp trình bao bọc 'container' của riêng chúng.

Ngoài ra, bạn không thể dựa vào ‘t.el.constructor’ ngay cả khi chúng là các đối tượng JS gốc. ‘Constructor’ không phải là một thuộc tính chuẩn, không có sẵn trong IE, và ngay cả trong Mozilla cũng không làm những gì bạn nghĩ. Tránh.

+0

Phần lớn điều này đã lỗi thời, và tôi không chắc nó có hoàn toàn đúng ngay cả khi được đăng. Cả [DOM Level 3] cũ (http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html) và [DOM Living Standard] hiện tại (http: // www .w3.org/TR/dom /) đưa ra tham chiếu rõ ràng tới * constructors * khi chỉ định giao diện và [ECMAScript 3] (http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ ECMA-262,% 203rd% 20edition,% 20December% 201999.pdf) (xem phần 4.2.1) và [ECMAScript 5] (http://www.ecma-international.org/ecma-262/5.1/#sec- 4.3.4) specs chỉ ra rằng một hàm tạo có thuộc tính 'prototype'. –

+0

Ngoài ra, thuộc tính hàm tạo * đã được * xác định cho các đối tượng gốc trong ECMAScript 3; chỉ CTRL-F cho '.constructor' hoặc' property constructor' trong http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999 .pdf. Tuy nhiên, nó có vẻ đúng, không có quy tắc chung nào là thuộc tính 'prototype' của hàm dựng phải có thuộc tính' constructor' chỉ về hàm tạo, vì vậy tôi nghĩ rằng các đối tượng host có thể có một ngớ ngẩn Thuộc tính 'constructor' không có thông số kỹ thuật vi phạm, nhưng trong thực tế chúng không. –

+0

Ngoài ra, trong phiên bản mới nhất của [Tiêu chuẩn sống DOM] (http://www.w3.org/TR/dom/), tất cả các đối tượng DOM được đảm bảo hoạt động hợp lý, vì chúng được khai báo sử dụng [WebIDL] (http://www.w3.org/TR/WebIDL), trong đó có một số đối tượng giao diện phải tồn tại như một thuộc tính của đối tượng chung trừ khi 'NoInterfaceObject' được chỉ rõ, và các đối tượng nguyên mẫu đó phải có' hàm tạo 'các thuộc tính trỏ đến đối tượng giao diện. Vì vậy, những gì ít mơ hồ spec vẫn trở lại trong năm 2009 và bây giờ dọn dẹp. –

4

Có thực sự không có cách nào để thực hiện việc này.

Các yếu tố IE dựa trên các đối tượng COM thực sự không cho phép các thành viên bổ sung được thêm vào giao diện của chúng (trong COM, giao diện là hợp đồng và không bao giờ nên thay đổi). Việc triển khai các giao diện này không thể được mở rộng bằng Javascript, các phần tử đơn giản không phải là nguyên mẫu.

IE thêm giao diện đặc biệt được thiết kế để làm việc với Javascript để cho phép thêm thành viên mới vào một cá thể cụ thể nhưng bạn không thể thêm thành viên mới vào 'lớp' vì không có nguyên mẫu.

0

Sau đây, cắt và dán từ bài viết HTMLElement doesnt work in IE. Các ví dụ hoạt động hoàn hảo trong IE và Firefox.

<html> 
<head> 
    <script type="text/javascript" src="DOMElement.js"></script> 
    <script type="text/javascript"> 

     var DOMElement = 
     { 
      extend: function(name,fn) 
      { 
       if(!document.all) 
        eval("HTMLElement.prototype." + name + " = fn"); 
       else 
       { 
        // 
        // IE doesn't allow access to HTMLElement 
        // so we need to override 
        // *document.createElement 
        // *document.getElementById 
        // *document.getElementsByTagName 
        // 

        //take a copy of 
        //document.createElement 
        var _createElement = document.createElement; 

        //override document.createElement 
        document.createElement = function(tag) 
        { 
         var _elem = _createElement(tag); 
         eval("_elem." + name + " = fn"); 
         return _elem; 
        } 

        //take copy of 
        //document.getElementById 
        var _getElementById = document.getElementById; 

        //override document.getElementById 
        document.getElementById = function(id) 
        { 
         var _elem = _getElementById(id); 
         eval("_elem." + name + " = fn"); 
         return _elem; 
        } 

        //take copy of 
        //document.getElementsByTagName 
        var _getElementsByTagName = document.getElementsByTagName; 

        //override document.getElementsByTagName 
        document.getElementsByTagName = function(tag) 
        { 
         var _arr = _getElementsByTagName(tag); 
         for(var _elem=0;_elem<_arr.length;_elem++) 
          eval("_arr[_elem]." + name + " = fn"); 
         return _arr; 
        } 
       } 
      } 
     }; 

     DOMElement.extend("foo",function(){alert('bar')}); 
     DOMElement.extend("about","DOMElement v0.1") 
     DOMElement.extend("contents",function(){return this.innerHTML}) 
     var elem = document.createElement("div"); 
     elem.foo(); 

     onload = function() 
     { 
      var elem2 = document.getElementById("myDiv"); 
      alert(elem2.about); 

      var divs = document.getElementsByTagName("div"); 
      for(var i=0;i<divs.length;i++) 
       alert(divs[i].contents()) 
     } 

    </script> 
</head> 
<body> 

    <div id="myDiv">hi</div> 
    <div id="div2">there</div> 

</body> 
</html> 

Thử Trân

+3

Không sử dụng ma quỷ 'eval' !!!!! Ví dụ, thay vì 'eval (" _ elem. "+ Name +" = fn ");' sử dụng '_elem [name] = fn;' – Oriol

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