UPDATE:(recap, fiddle và tiền thưởng)JavaScript: Làm thế nào để mô phỏng sự kiện thay đổi trong internet explorer (đoàn)
Câu hỏi này chưa được nhận được quá nhiều sự chú ý, vì vậy tôi sẽ dành một số đại diện cho nó. Tôi biết tôi có xu hướng quá chi tiết trong cả câu trả lời và câu hỏi của mình. Đó là lý do tại sao tôi đã đi trước và thiết lập this fiddle, theo quan điểm của tôi, một biểu diễn phong nha về loại mã mà tôi hiện đang phải sử dụng để đến gần sự kiện sôi nổi change
. Một vài vấn đề tôi đang cố gắng giải quyết:
- Sự kiện
pseudo-change
không kích hoạt trên phần tử đã chọn, trừ khi nó không tập trung. Trong một số trường hợp, khách hàng sẽ được chuyển hướng khi chọn một giá trị mới. Làm thế nào để đạt được điều này? - Trình xử lý được gọi là cả khi nhãn được nhấp, cũng như hộp kiểm. Bản thân nó là những gì bạn mong đợi, nhưng do sự kiện sủi bọt nó (AFAIK) không thể xác định yếu tố nào được nhấp vào. Đối tượng sự kiện của IE không có thuộc tính
realTarget
. - Khi thay đổi
checked
-trường hộp kiểm trong IE bằng cách nhấp vào nhãn, tất cả đều tốt (mặc dù nó yêu cầu một số giải pháp khó chịu), nhưng khi nhấp vào hộp kiểm trực tiếp, trình xử lý được gọi, nhưng trạng thái đã chọn vẫn không thay đổi, cho đến khi tôi nhấp lần thứ hai. Sau đó, giá trị thay đổi, nhưng trình xử lý không được gọi. - Khi tôi chuyển sang một tab khác và ngược lại, trình xử lý được gọi nhiều lần. Ba lần nếu trạng thái đã chọn thực sự thay đổi, hai lần nếu tôi nhấp trực tiếp vào checbox một lần.
Mọi thông tin có thể giúp tôi giải quyết một hoặc nhiều vấn đề ở trên sẽ được đánh giá cao. Xin vui lòng, tôi không quên thêm một thẻ jQuery, tôi thích JS thuần túy, vì vậy tôi đang tìm kiếm một câu trả lời JS thuần túy.
Tôi có một trang web với hơn 250 phần tử được chọn trên đó và 20 ~ 30 hộp kiểm. Tôi cũng phải theo dõi hành động của người dùng và thực hiện các hành động thích hợp. Do đó, tôi rất tự nhiên khi đại diện cho sự kiện thay đổi, thay vì sau đó thêm hàng trăm người nghe, IMHO.
Tất nhiên, chính sách của IE: IE8 phải được hỗ trợ - không kích hoạt sự kiện trao đổi khi tôi cần. Vì vậy, tôi đang cố gắng giả mạo một sự kiện onchange. Những gì tôi có cho đến nay là làm việc hợp lý tốt ngoài 1 điều mà thực sự lỗi tôi.
Tôi đang sử dụng onfocusin
và onfocusout
để đăng ký sự kiện. Trong một số trường hợp, khi người dùng chọn một giá trị mới từ phần tử chọn, tập lệnh sẽ phản hồi ngay lập tức. Tuy nhiên, miễn là lựa chọn không bị mất tiêu điểm, điều này sẽ không xảy ra.
Đây là những gì tôi đã đưa ra cho đến nay:
i = document.getElementById('content');
if (!i.addEventListener)
{
i.attachEvent('onfocusin',(function(self)
{
return function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
switch (target.tagName.toLowerCase())
{
case 'input':
if (target.getAttribute('type') !== 'checkbox')
{
return true;
}
return changeDelegator.apply(self,[e]);//(as is
case 'select':
self.attachEvent('onfocusout',(function(self,current)
{
return function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
if (target !== current)
{
return;
}
self.detachEvent('onfocusout',arguments.callee);//(remove closure
return changeDelegator.apply(self,[e]);
}
})(self,target));
default: return;
}
}
})(i));//(fake change event, buggy
}
else
{//(to put things into perspective: all major browsers:
i.addEventListener('change',changeDelegator,false);
}
Tôi đã thử gắn một sự kiện nghe bên trong handler onfocusin
, ràng buộc với sự kiện onclick
. Nó kích hoạt sự kiện onfocusout
của bất kỳ lựa chọn nào có tiêu điểm ATM. Vấn đề duy nhất là, 99,9% người dùng sẽ nhấp vào một lựa chọn, do đó, sự kiện focusin
cũng kích hoạt tính năng onclick.
Để làm tròn điều đó, tôi đã tạo bao đóng và chuyển tiêu chí chọn lọc hiện tại và giá trị ban đầu của nó thành đối số.Nhưng một số người dùng làm sử dụng bàn phím của họ và những người dùng này thường tab đến hộp chọn tiếp theo mà không thay đổi giá trị. Mỗi lần ràng buộc một người nghe onclick mới ... Tôi tin rằng có HAS là một cách dễ dàng hơn để kiểm tra tất cả e.type
và xử lý chúng một cách riêng biệt.
Cũng như một ví dụ: mã với một phụ onclick
nghe: tất cả các mã cũng giống như đoạn đầu tiên, vì vậy tôi chỉ dán case 'select':
khối
case 'select':
self.attachEvent('onfocusout',(function(self,current)
{
return function(e)
{
e = e || window.event;//(IE...
var target = e.target || e.srcElement;
if (!(target === current))
{
return;
}
self.detachEvent('onfocusout',arguments.callee);//(remove closure
return changeDelegator.apply(self,[e]);
};
})(self,target));
self.attachEvent('onclick',(function(self,current,oldVal)
{
return function(e)
{
e = e || window.event;
var target = e.target || e.srcElement;
if (target.tagName.toLowerCase() === 'option')
{
while(target.tagName.toLowerCase() !== 'select')
{
target = target.parentNode;
}
}
if (target !== current)
{//focus lost, onfocusout triggered anyway:
self.detachEvent('onclick',arguments.callee);
return;
}
var val = target.options[target.selectedIndex].innerHTML;//works best in all browsers
if (oldVal !== target.options[target.selectedIndex].innerHTML)
{
self.detachEvent('onclick',arguments.callee);
return target.fireEvent('onfocusout');
}
};
})(self,target,target.options[target.selectedIndex].innerHTML));
default: return;
1. Có, tôi chắc chắn về điều đó: sự kiện thay đổi được kích hoạt trong IE8, nhưng nó không bị bong bóng. Đó là [một vấn đề đã biết] (http://stackoverflow.com/questions/5146784/make-form-elements-onchange-bubble-in-internet-explorer) 2. trình xử lý thay đổi được gọi trong cả hai trường hợp, đó không phải là vấn đề. Tuy nhiên, khi nhấp vào nhãn, trình xử lý được gọi sau khi trạng thái đã chọn đã thay đổi, trong khi trạng thái đã chọn sắp thay đổi khi hộp kiểm được nhấp trực tiếp. Vì vậy, nếu 'target.checked === true', nó đã được kiểm tra chưa, hoặc nó có bị bỏ chọn không? Không có cách nào để kể. Chạy ra khỏi ký tự –
3. Thêm mờ và tiêu điểm khiến IE bị lỗi: lưu ý rằng, vì 'onchange' không tạo bọt tôi đang sử dụng các sự kiện' onfocusin' và 'onfocusout'. Nếu trình xử lý làm mờ, và tập trung, nó sẽ chỉ tiếp tục gọi chính nó là vô hạn 4. Và bằng cách xử lý, tôi có nghĩa là cả hai: nghiêm chỉnh nói 'changeDelegator' chỉ là một hàm, nhưng tôi gọi trong ngữ cảnh của trình xử lý (' changeDelegator. áp dụng (điều này, [e]); '), vì vậy tôi coi nó là một sự kéo dài/tiếp tục của trình xử lý thực tế. Tôi biết 'focusin' được kích hoạt khi tab được _revived_, nhưng nó được kích hoạt cho mỗi sự kiện được xử lý bởi hàm đại biểu. chars .... –
Ý tôi là điều cuối cùng đơn giản là: tôi bấm vào một hộp kiểm (trình xử lý được kích hoạt, nhưng trạng thái đã chọn không thay đổi!), Nếu tôi nhấp vào hộp kiểm đó lần thứ hai, thì trình xử lý là không không được gọi, nhưng trạng thái đã kiểm tra thay đổi như nhau. Nếu tôi không nhấp vào nó lần thứ hai, nhưng chuyển đổi tab và ngược lại, sự kiện 'focusin' sẽ xuất hiện _not_ để được gọi cho hộp kiểm đó tôi đã nhấp một lần. Thật kỳ lạ. Về mặt hiệu suất: có sự khác biệt lớn, đặc biệt là khi _not_ chạy trên V8. gắn nó vào mỗi phần tử trên toàn bộ trang sẽ thêm đến 333 (chỉ cần đếm tất cả) elems! chars ... –