2009-03-30 25 views
14

Tôi có hai < chọn> các hộp trên biểu mẫu. Chọn một mục trong hộp < chọn> đầu tiên sẽ xác định nội dung sẽ xuất hiện trong lựa chọn thứ hai <> (Sử dụng Ajax http_request).Cách nhanh hơn để điền <select> bằng Javascript

Trong một số trường hợp, có thể có 500 mục (đoán) lớn trong lựa chọn thứ hai và mất 5-10 giây để cập nhật trong IE. Firefox dường như hoạt động hoàn hảo.

Tôi tự hỏi nếu có cách nào nhanh hơn để đạt được điều này. Hiện tại, máy chủ tạo một chuỗi sẽ chuyển nó tới máy khách sau đó được chia nhỏ và thêm từng mục vào phần chọn bằng cách tạo phần tử tùy chọn và sau đó thêm nó vào lựa chọn <>.

tôi đã cố gắng tạo ra toàn bộ chọn mục như là một chuỗi trên máy chủ và thêm rằng mẫu nhưng vì một lý do nó sẽ không làm việc trong Firefox (một cái gì đó bỏ lỡ?)

Cảm ơn

Trả lời

2

Đặt nó bằng cách sử dụng SelectElement.innerHTML sẽ là nhanh nhất ... nhưng that FAILS in IE.

ngoái, tôi đã kiểm tra, bạn có thể làm điều này trong IE, nếu bạn quấn tất cả các tùy chọn trong một giả <div> thẻ, hoặc thiết lập toàn bộ .outerHTML của danh sách lựa chọn trong IE.

0

Sẽ rất hữu ích khi xem mã của bạn.

NẾU bạn đang tạo một <option> yếu tố phụ thêm nó mỗi lần lặp, bạn nên xem xét việc tạo ra tất cả các <option> yếu tố cùng một lúc, và sau đó phụ thêm chúng cùng một lúc.

Vì vậy (trong psuedocode):

// Don't do this: 
for choice in choices: 
    option = new Options(choice) 
    select.append(option) 


// Do this instead 
var options = array() 

for choice in choices: 
    options.append(new Options(choice)) 

for option in options: 
    select.append(option) 

// Or you might try building the select element off-screen and then appending to the DOM 
var options = array() 
var select = new SelectElement() 

for choice in choices: 
    select.append(new Options(choice)) 

dom_element.append(select) 
+0

như thế nào sử dụng sự giúp đỡ mảng? bạn vẫn cần phải gọi {n} nối vào danh sách chọn (đó là nguyên nhân gây ra vấn đề tốc độ, vì trình duyệt cần xác định sau mỗi lần thêm nếu kích thước danh sách cần được cập nhật) – scunliffe

+0

@scunliffe - tối ưu hóa trình duyệt hiếm khi xuất hiện xuống phân tích phức tạp Big-O. Tôi đoán ở đây là IE có thể trì hoãn việc hiển thị các phần tử Tùy chọn mới cho màn hình nếu tất cả chúng được đính kèm với DOM cùng một lúc, điều này sẽ đẩy nhanh tốc độ. Chỉ cần một cái gì đó để thử. – Triptych

1

tôi sẽ tạo ra toàn bộ chọn trên máy chủ và tiêm nó vào trang. Cách tiếp cận đó bỏ qua sự khác biệt của trình duyệt gây phiền nhiễu và làm giảm độ phức tạp của mã phía máy khách.

Bạn đã đề cập rằng bạn đã thử điều đó nhưng không thành công trong firefox. Tôi khuyên bạn nên kiên trì làm cho nó hoạt động, đăng một câu hỏi khác yêu cầu trợ giúp về vấn đề đó hoặc chỉnh sửa câu hỏi của bạn để cho chúng tôi thấy những gì bạn đã làm không hoạt động trong firefox.

19

500 yếu tố không nhiều, ngay cả đối với IE. Bạn phải làm một cái gì đó khác để gây ra sự chậm trễ.

Tôi vừa thử với hơn 500 tùy chọn trong IE6, IE7, FF2 và FF3 và tất cả đều gần ngay lập tức. Tôi đã sử dụng mã này:

var data = [ 
    { text: 'foo', value: 'bar' }, 
    // ... 
    { text: 'foo', value: 'bar' } 
]; 

var select = document.getElementsByTagName('select')[0]; 
select.options.length = 0; // clear out existing items 
for(var i=0; i < data.length; i++) { 
    var d = data[i]; 
    select.options.add(new Option(d.text, i)) 
} 

Tôi khuyên bạn nên lược tả bit mã đang tìm nạp dữ liệu và điền vào trình đơn thả xuống. Một cái gì đó khác có thể chiếm thời gian. Ví dụ: hãy kiểm tra xem mã có "chia nhỏ" giá trị chuỗi được trả về từ máy chủ có sắc nét không (có vẻ như bạn đang thực hiện phân tích cú pháp tùy chỉnh của riêng mình ở đó).

+5

Um ... không phải là 'select.options.add (tùy chọn mới (d.text, d.value))'? – tzot

0

Khi tôi sử dụng phiên bản đầu tiên của việc này nó hoạt động nhưng có thể rất chậm trong việc cập nhật thứ hai chọn

 
<html> 
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'> 
<table> 
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> 
<tr><td><select id='selectid'></select></td></tr> 
</table> 
</form> 
</html> 

<script type=\"text/javascript\"> 
function UPDATE(updatedata) 
{     
    var itemid = document.getElementById('selectid');    

    var data = updatedata.split('|'); 
    var len = data.length;               

    for(i=0; i < len; i ++) 
    { 
     var opt = document.createElement('option'); 
     opt.text = data[i]; 

     try 
     { 
      itemid.add(opt, null);       
     } 
     catch(ex) 
     { 
      itemid.add(opt);  
     }  
    }           
} 
</script> 

phiên bản này hoạt động trong IE, nhưng firefox dường như không gửi sẽ chọn dữ liệu thứ hai. Tôi đã bỏ lỡ một cái gì đó với điều này.

 
<html> 
<form id='myform' method='post' action='$_SERVER[PHP_SELF]'> 
<table> 
<tr><td><select onselect='CALL_AJAX_AND_UPDATE();'></select></td></tr> 
<tr><td><div id='addselect'></div></td></tr> 
</table> 
</form> 
</html> 

<script type=\"text/javascript\"> 
function UPDATE(updatedata) 
{    
    // update data is full select html 
    var itemid = document.getElementById('addselect');    
    itemid.innerHTML = updatedata;               
} 
</script> 
2

Vấn đề với tất cả các câu trả lời này với SelectElement.innerHTML là bạn không thể thực hiện thủ thuật này bằng SELECT. Giải pháp là sử dụng innerHTML trên PARENT của chính phần tử SELECT. Vì vậy, trong ajax/jquery của bạn/bất cứ điều gì mã tạo ra một chuỗi có chứa TẤT CẢ của SELECT HTML, và sau đó nhận được chủ sở hữu (một div hoặc span hoặc bất cứ điều gì) và thiết lập innerHTML vào chuỗi bạn đã xây dựng.

Bạn sẽ cần cách ly SELECT khỏi trang và cung cấp cho nó phần tử cha mẹ rõ ràng (span hoặc div) để ngăn các phần tử html khác bị thương vong khi bạn hủy/tạo lại phần tử SELECT.

Câu trả lời ngắn:

parentselectelement.removeChild(selectelement); 
parentselectelement.innerHTML = "<select ...><options...></select>"; 
1

Đừng quên gắn liền với các document.createDocumentFragment() đầu tiên, trước khi phụ thêm đó đến SELECT.

4

Mã đầu tiên là tốt nhưng công trình này tốt hơn cho tôi:

var data = [ 
    { text: 'uno', value: '1' }, 
    {text: 'dos', value: '2' } 
]; 

var select = document.getElementById('select-choice-1'); 
select.options.length = 0; // clear out existing items 
for (var i = 0; i < data.length; i++) { 
    var d = data[i]; 
    select.options.add(new Option(d.text, d.value)) 
} 
0

Tôi thích câu trả lời Crescent tươi và Kemal Fadillah kể từ khi cả hai sử dụng:

select.options.add(new Options(name, value)) 

Đối với các đối tượng dữ liệu tôi đề nghị một tinh chỉnh nhỏ như sau:

var data = { 
    'uno': 1, 
    'dos': 2 
}; 

var select = document.getElementById('select-choice-1'); 
select.options.length = 0; // clear out existing items 
for (var i in data) { 
     select.options.add(new Option(i, data[i])); 
} 
0

Nếu bạn không ngại sử dụng CoffeeScript thì mã sau đây e điền vào một danh sách lựa chọn với dữ liệu JSON trong một vài dòng.

HTML

<select id="clients"></select> 

CoffeeScript

fillList=($list, url)=> 
    $.getJSON(url) 
    .success((data)-> 
     $list 
     .empty() 
     .append("<option value=\"#{item.Id}\">#{item.Name}</option>" for item in data) 
    ) 

$ -> 
    fillList($('#clients'), '/clients/all') 

Note: Các vòng lặp bên trong append tạo ra toàn bộ chuỗi html trước khi gọi các append phương pháp lần. Điều này là tốt đẹp và hiệu quả.

Ví dụ JSON

[ 
    {"Id":"1","Name":"Client-1"}, 
    {"Id":"2","Name":"Client-2"} 
] 
Các vấn đề liên quan