2010-11-03 39 views
23

Tôi đã gặp sự cố này một vài lần và tôi không hài lòng với các giải pháp mà tôi đã sử dụng trước đây.Làm cách nào để kích hoạt sự kiện Javascript blur sau khi sự kiện nhấp gây ra hiện tượng mờ?

Tôi có hộp nhập liệu có sự kiện làm mờ xác thực nội dung của nó và nút sẽ điền vào hộp nhập khi nhấp. Vấn đề là nhấp vào nút kích hoạt sự kiện làm mờ đầu vào và sau đó nhấp vào sự kiện nhấn nút để nội dung được chèn bởi nút không phải là những gì được xác thực.

Xem http://jsfiddle.net/jakecr/dL3K3/

Tôi biết đây là hành vi đúng nhưng tôi không thể nghĩ ra một cách sạch sẽ để có được xung quanh vấn đề này.

+0

Câu hỏi của bạn không rõ ràng? vấn đề của bạn và giải pháp dự kiến ​​là gì? –

+0

Về cơ bản, một hành động của người dùng gây ra hai sự kiện kích hoạt theo thứ tự nhưng hành động của sự kiện thứ hai phụ thuộc vào sự kiện đầu tiên. Tôi đã xem xét việc sử dụng setTimeout để trì hoãn sự kiện đầu tiên, nhưng điều đó dường như không phải là một giải pháp lý tưởng. – Jake

+0

Tôi đã hỏi câu hỏi này ở dạng khá chung vì tôi đã gặp phải vấn đề này một vài lần trong các trường hợp khác nhau. – Jake

Trả lời

31

Chúng tôi gặp sự cố tương tự khi làm việc. những gì chúng tôi đã tìm ra vào cuối là sự kiện được tổ chức sẽ kích hoạt trước sự kiện mờ cho phép bạn đặt nội dung trước khi xác thực hoặc thậm chí hủy quá trình xác thực hoàn toàn bằng cờ.

séc fiddle này tôi đã sử dụng example- bạn http://jsfiddle.net/dL3K3/31/

$(function(){ 
    var flag = true; 
    $('input').blur(function(){ 
     if(!$(this).val() && flag){ 
      alert("Grrr, It's empty"); 
     } 
    }); 

    $('button').mousedown(function(){ 
     flag = false; 
    });  
    $('button').mouseup(function(){ 
     flag = true; 
     $('input').val('content').focus(); 
    }); 

}); 

-Edit-

Như @mclin đề nghị, bằng cách sử dụng sự kiện mousedown và preventDefault sẽ ngăn chặn hành vi mờ. Và bạn chỉ có thể rời khỏi sự kiện click ban đầu nguyên vẹn -

http://jsfiddle.net/dL3K3/364/

$(function(){ 
    $('input').blur(function(){ 
     if(!$(this).val()){ 
      alert("Grrr, It's empty"); 
     } 
    }); 

    $('button').mousedown(function(e){ 
     e.preventDefault(); 
    });  
    $('button').click(function(){ 
     $('input').val('content'); 
    }); 

}); 

Giải pháp này có thể là một chút sạch hơn và tốt hơn cho hầu hết các trường hợp chỉ cần lưu ý rằng nếu bạn sử dụng nó bạn sẽ preventDefault và mờ của bất kỳ yếu tố nào khác mà tiêu điểm hiện đang ở nhưng đối với hầu hết các trường hợp sử dụng không phải là vấn đề.

+0

sự kiện được tổ chức có thể khiến quá trình gửi xảy ra bất kể xác thực xem tại đây http://stackoverflow.com/questions/43011387/mousedown-still-submitting-form-when-it-should-not – DragonFire

+0

@DragonFire Điều này không liên quan gì đến vấn đề này hoặc mouswdown. Mã của bạn đang chạy không đồng bộ và xử lý mã của bạn là mã đồng bộ –

1

Phân tách logic xác thực nhập thành chức năng riêng của nó, được gọi tự động cả sự kiện mờ và sau đó là sự kiện nhấp sau khi bạn đã sửa đổi giá trị trong hộp nhập. Đúng logic xác thực của bạn sẽ được gọi hai lần, nhưng tôi không nhìn thấy một cách xung quanh mà không làm thay đổi nhiều hơn nữa.

Ví dụ sử dụng jQuery:

$('input').blur(function() { 
    validate(this); 
}); 

$('submit').click(function() { 
    //modify the input element 
    validate(inputElement); 
}); 

var validate = function(obj) { 
    // validate the object 
} 
+0

Không hoàn toàn là giải pháp tôi đã làm sau khi sự kiện mờ vẫn được kích hoạt, nhưng tôi không nghĩ rằng nó có thể làm chính xác những gì tôi muốn. – Jake

8

này cũng có thể giúp:

Thiết lập một bộ đếm thời gian mà trì hoãn hành động sự kiện mờ trước khi nó cháy sự kiện nhấn nút.

// Namespace for timer var setTimer = { timer: null } 

    $('input,select').blur(function() { 
     setTimer.timer = setTimeout(function() { 
      functionCall(); 
     }, 1000); 
    }); 

    $('input,select').focus(function() { 
     setTimer.timer = setTimeout(function() { 
      functionCall(); 
     }, 1000); 
    }); 

    $("#btn").click(function() { 
     clearTimeout(setTimer.timer); 
     functionCall(); 
    }); 
+0

Đây là giải pháp thông minh. –

-2

Bí quyết không sử dụng các sự kiện mờ và nhấp vì chúng luôn được thực hiện theo thứ tự mờ trước tiên, nhấp vào giây. Thay vào đó bạn nên kiểm tra khi phần tử có tiêu điểm đã thay đổi, bởi vì điều đó chỉ xảy ra sau khi nhấp chuột.

Tôi nghĩ rằng tôi có một giải pháp thanh lịch cho một này:

var alreadyValidated = 'true'; 

setInterval(function(){ 
    if(document.activeElement.id != 'validation-field-id'){ 
     if(alreadyValidated=='false'){ 
      alreadyValidated = 'true'; 
      validate(document.activeElement);  
     } 
    } 
    else { 
     alreadyValidated = 'false'; 
    } 
}, 200); 

Những ngày này tất cả các trình duyệt hiện đại hỗ trợ document.activeElement.

+2

Bạn nên sử dụng 'true' và' false' thay vì chuỗi vì 'Boolean ('false') === true' – Jake

+7

" Elegant Solution "và setInterval không thuộc cùng một bài đăng. – aaronsnoswell

18

Tôi có giải pháp tốt hơn so với Yoni Jah's: gọi ngăn chặnDefault trên sự kiện được tổ chức của nút.OnBlur không bao giờ xảy ra vì vậy bạn được tự do làm bất cứ điều gì trong sự kiện nhấp chuột.

Điều này là tốt hơn bởi vì nó không thay đổi hành vi nhấp chuột bằng cách làm cho mọi thứ xảy ra khi di chuột xuống thay vì di chuột lên, điều này có thể không mong muốn.

+0

Đây là giải pháp tốt nhất. Chính xác những gì tôi đang tìm kiếm. –

+0

Cảm ơn tôi đã cập nhật câu trả lời của mình –

0

Thỉnh thoảng hữu ích khi có đối tượng con khi di chuột lên, nhưng cha mẹ muốn ẩn con của nó khi làm mờ. Chúng ta có thể hủy bỏ trốn trong những yếu tố trẻ em, sau đó chờ đợi cho đến khi mouseup của chúng tôi xảy ra, sau đó buộc mờ xảy ra khi chúng tôi sẵn sàng

js

var cancelHide = false; 

$('.my-input').blur(function() { 
    if (!cancelHide) { 
     $('.my-item').hide(); 
    } 
}); 

$('.my-input').click(function() { 
    $('.my-item').show(); 
}); 

$('.my-item').mousedown(function() { 
    cancelHide = true; 
}); 

$('.my-item').mouseup(function() { 
    var text = $(this).text(); 
    alert(text); 
    cancelHide = false; 
    $('.my-input').blur(); 
}); 

html

<input type="text" class="my-input"/> 
<div class="my-item">Hello</div> 
<div class="my-item">Lovely</div> 
<div class="my-item">World</div> 

css

.my-item { 
    display:none; 
} 

https://jsfiddle.net/tic84/on421rxg/

Nhấp vào mục danh sách sẽ chỉ nhanh nhẹn trong mouseup, mặc dù phụ huynh cố gắng che giấu chúng trên mờ

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