2009-03-04 18 views
9

Tôi đã viết một số Javascript để cho phép chỉnh sửa danh sách các mục trong một biểu mẫu HTML, bao gồm việc thêm và xóa các mục. Có nó hoạt động trong Firefox. Khi thử nó trong Internet Explorer, tôi thấy rằng bất kỳ mục bổ sung nào không được gửi cùng với biểu mẫu.IE không gửi; các yếu tố hình thức được thêm động; đây có phải là lỗi của IE không?

Dài câu chuyện ngắn ... rất nhiều đơn giản hóa, gỡ lỗi, đã tìm ra dòng nào đang kích hoạt IE để bỏ qua đầu vào biểu mẫu mới. Vì vậy, vấn đề hành vi được giải quyết.

Nhưng bây giờ tôi phải hỏi: Tại sao? Đây có phải là lỗi của IE không?

Đây là mã đơn giản:

<html> 
<head> 
    <title>Test</title> 
    <script type="text/javascript"> 
     function add() { 
      div = document.getElementById("mylist"); 

      // *** Adding text here works perfectly fine. *** 
      div.innerHTML += " "; 

      e = document.createElement("input"); 
      e.setAttribute("type", "text"); 
      e.setAttribute("name", "field3"); 
      e.setAttribute("value", "--NEWVALUE--"); 
      div.appendChild(e); 

      // *** Adding text here works perfectly fine in Firefox, but for 
      //  Internet Explorer it causes field3 to not be submitted. *** 
      //div.innerHTML += " "; 
     } 
    </script> 
</head> 
<body> 
    <form action="" method="get"> 
     <div id="mylist"> 
      <input type="text" name="field1" value="value1" /> 
      <input type="text" name="field2" value="value2" /> 
     </div> 
     <a href="javascript:" onclick="add()" />Add</a> 
     <input type="submit" value="Submit" /> 
    </form> 
</body> 
</html> 

Để thử nó ra, làm rõ ràng: tải trong IE, bấm Add, nhấn Submit, nhìn những gì trong thanh địa chỉ. Nếu bạn bỏ ghi chú dòng cuối cùng trong add(), IE sẽ đột ngột ngừng báo cáo field3. Nó hoạt động tốt trong Firefox.

Bất kỳ ý tưởng nào? Một tâm trí tò mò muốn biết. (Và làm cách nào để thêm văn bản vào đó nếu cần, theo kiểu di động, vì vậy IE rất vui?)

Trả lời

7

Đây có phải là lỗi IE không?

Dường như vậy. Khi bạn tạo một phần tử < input> thông qua các phương thức DOM, IE không nhận được thuộc tính ‘name’. Nó sắp xếp trong đó yếu tố không gửi, nhưng nếu bạn cố gắng để có được một biểu diễn ‘innerHTML’ của phần tử nó biến mất một cách bí ẩn. Điều này không xảy ra nếu bạn tạo phần tử bằng cách viết trực tiếp vào innerHTML. Ngoài ra, nếu bạn sử dụng các phương thức điều hướng biểu mẫu DOM Cấp 0, như 'myform.elements.x.value', truy cập thông qua mảng 'phần tử' có thể không hoạt động (tương tự như truy cập trực tiếp 'myform.x' một số người sử dụng sai cách sử dụng). Trong mọi trường hợp, những ngày này bạn có thể thích getElementById().

Vì vậy, hoặc sử dụng innerHTML hoặc sử dụng các phương pháp DOM; tốt nhất là không trộn chúng khi tạo các trường biểu mẫu.

Đây là documented (see ‘Remarks’) và cuối cùng được khắc phục trong IE8.

Trong mọi trường hợp, không bao giờ làm:

div.innerHTML + = '...';

Đây là chỉ đường cú pháp cho:

div.innerHTML = div.innerHTML + '...';

Nói cách khác, nó phải nối tiếp toàn bộ nội dung HTML con của phần tử, sau đó thực hiện chuỗi nối, sau đó phân tích lại chuỗi mới thành phần tử, vứt bỏ toàn bộ nội dung gốc. Điều đó có nghĩa là bạn mất mọi thứ không thể được tuần tự hóa: cũng như các thuộc tính 'tên' không có thật của IE cũng có nghĩa là bất kỳ trình xử lý sự kiện JavaScript, Trình nghe DOM hoặc các thuộc tính tùy chỉnh khác mà bạn đã đính kèm với từng phần tử con. Ngoài ra, chu trình tuần tự/phân tích cú pháp không cần thiết là chậm.

3

IE rất kén chọn thay đổi một số thuộc tính tích hợp trong thời gian chạy. Ví dụ, tên của một phần tử đầu vào không thể thay đổi trong khi thiết lập.

Hai điều tôi sẽ cố gắng nếu tôi là bạn:

  1. Thay vì sử dụng setAttribute(), hãy thử đặt name, typevalue tính một cách rõ ràng:

    e.name = "text";

  2. Nếu doesn này Không hoạt động, bạn có thể phải bao gồm tất cả các thuộc tính này vào cuộc gọi document.createElement():

    var e = document.createElement("<input type='text' name='field'>");

    điều này thực sự có thể gây ra ngoại lệ trong một số trình duyệt. Vì vậy, cách trình duyệt chéo tốt nhất để đi là:

.

var e; 
    try { 
    e = document.createElement("<input type='text' name='field'>"); 
    } catch (ex) { 
    e = document.createElement("input"); 
    e.type = 'text'; 
    e.name = 'field'; 
    } 
    e.value = 'value'; 
+0

1 về tránh setAttribute. -1 trên cuộc gọi createElement-with-markup, đây là một bản hack chỉ gây khó chịu cho IE. – bobince

+0

Tôi đồng ý về việc đó là một hack - đó là lý do tại sao tôi đề xuất áp phích thử thiết lập các thuộc tính trước tiên. Nếu điều đó không hiệu quả, tôi không thấy cách nào khác để làm những gì anh ta muốn xảy ra. – levik

3

Cảm ơn bobince và levik về câu trả lời của bạn. Sử dụng chúng và một số thử nghiệm khác, đây là kết luận của tôi:

  1. Có lỗi IE.

  2. IE 8 sửa lỗi theo Microsoft: "Internet Explorer 8 trở lên có thể đặt thuộc tính NAME ở thời gian chạy trên các phần tử được tạo động với phương thức createElement."

  3. Lỗi này: Gọi số e.setAttribute("name", "field3") chỉ loại đặt tên. Nó sẽ hoạt động nếu không có gì khác xảy ra với phần tử, nhưng nếu được yêu cầu để tuần tự hóa, tên không được đăng. Vì vậy, khi tôi nói innerHTML += " " buộc một serialization, mà mất tên, vì vậy nó đã không được phục hồi khi deserialization. Không có tên, không bao gồm trong việc gửi biểu mẫu.

  4. Cách giải quyết # 1: e = document.createElement("<input name='field3' />") sẽ hoạt động, ngay cả khi phải đối mặt với tuần tự hóa.

  5. Cách giải quyết # 2: Thay vì thêm văn bản sử dụng innerHTML + =, tôi có thể nối thêm phần tử văn bản như sau: div.appendChild(document.createTextNode(" "));. Tôi đã tìm ra phải có một cách tốt hơn để thêm văn bản, và bây giờ tôi biết nó :-).

Chúc mừng,
--jsf

+0

Tôi đang thêm nhiều phần tử thông qua document.createElement và mỗi phần tử có nhiều thuộc tính..Một thuộc tính là ID. Tôi cũng có một hàm javascipt trên cùng một trang lấy ID thông qua document.getElementById (ID) và innerHTML. Làm cách nào để tôi tham chiếu hoặc lấy phần tử chính xác dựa trên ID của phần tử được tạo động?Tôi đang sử dụng IE 8 ..works trong Firefox :) – Jim

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