2010-04-21 22 views
43

Có điều gì tôi có thể làm như thế này (perhap qua một plugin)Có 'trọng tâm' trong JavaScript (hoặc jQuery) không?

if (! $('form#contact input]').hasFocus()) { 
    $('form#contact input:first]').focus(); 
} 

Về cơ bản, đặt trọng tâm vào các đầu vào đầu tiên, nhưng chỉ khi người dùng đã chưa nhấp vào bất cứ điều gì?

Tôi biết điều này cũng sẽ hoạt động, nhưng có điều gì thanh lịch hơn không?

$(function() { 
    var focused = false; 
    $('form#contact input]').focus(function() { 
    focused = true; 
    }); 
    setTimeout(function() { 
    if (! focused) {  
     $('form#contact input:first]').focus(); 
    } 
    }, 500); 
}); 

Trả lời

62

Không có giải pháp tự nhiên nhưng có có một thanh lịch hơn cách bạn có thể thực hiện:

jQuery.extend(jQuery.expr[':'], { 
    focus: "a == document.activeElement" 
}); 

Yo bạn đang định nghĩa một bộ chọn mới. Xem Plugins/Authoring. Sau đó, bạn có thể làm:

if ($("...").is(":focus")) { 
    ... 
} 

hay:

$("input:focus").doStuff(); 
+0

Đó là Cletus thú vị, không bao giờ về một bộ chọn tùy chỉnh! – alex

+6

Có lẽ bạn nên gửi điều này cho các phiên bản mới hơn của jQuery, nó sẽ hữu ích. – gnarf

+0

Bất kỳ ý tưởng nào tại sao 'jQuery.expr' sử dụng' == 'thay vì' === '? –

7

Không, không có.

Tuy nhiên, bạn có thể mô phỏng nó như thế này:

$(':input') 
    .data('focused', false) 
    .focus(function() { $.data(this, 'focused', true); }) 
    .blur(function() { $.data(this, 'focused', false); }); 
+0

Tại sao điều này lại bị bỏ phiếu? – SLaks

+0

tất cả các câu trả lời là ngoại trừ của Vincent (bấm vào chúng). Tôi đang +1 tất cả chúng để chống lại điều đó. – cletus

+0

Không biết về các downvotes. Có lẽ họ đã làm điều đó khi câu trả lời của bạn chỉ là dòng đầu tiên. Dù sao, tôi đã cho bạn một +1 :) – alex

26

$('input:focus')

Đó là CSS. Bạn không cần tạo "công cụ chọn tùy chỉnh". Nó đã tồn tại! http://www.w3schools.com/CSS/pr_pseudo_focus.asp

Chỉ cần đính kèm bất kỳ quy trình nào bạn muốn thực hiện cho bộ chọn đó và nó sẽ loại bỏ nó nếu phần tử được đề cập không được tập trung. Tôi đã thực hiện việc này gần đây để giữ một số keyup từ việc khởi tạo kiểm tra lỗi nhập email khi đầu vào e-mail không được sử dụng.

Nếu tất cả các bạn đang cố gắng làm là kiểm tra xem người dùng đã tập trung vào bất cứ điều gì mình, chỉ cần làm điều này:

if($('input:focus').size() == 0){ 
    /* Perform your function! */ 
} 
+1

Bạn đang sai. jQuery, không giống như CSS, không có bộ chọn ': focus' hoặc': hover'. – SLaks

+2

Dường như nó thực sự: http://jsfiddle.net/vnYCK/ – Matt

+1

jQuery sử dụng bộ chọn CSS. Nếu nó hoạt động trong CSS, nó hoạt động trong jQ. Tin tôi đi. Nếu bạn có bất kỳ nghi ngờ nào, hãy thử biểu mẫu trong trang này và sau đó kiểm tra JS: http://www.ddrewdesign.com/contact/ Mã kích hoạt là trên dòng 124. Tôi chưa thử ': hover' trước đó, vì vậy Tôi không thể nói cho điều đó. Bí quyết là làm cho JS thực hiện công việc legwork để nó có thể kiểm tra, vì vậy bạn phải đặt nó vào trong một hành động nào đó. – dclowd9901

9

tôi đã gặp rắc rối với cách tiếp cận cletus, sử dụng jQuery 1.3.2 và Firefox 3.6. 8, bởi vì chuỗi "a == document.activeElement" không phải là hàm hợp lệ.

Tôi đã sửa nó xác định chức năng cho khóa focus. Trên thực tế, tất cả các khóa khác được xác định trong jQuery.expr[':'] được định nghĩa là các hàm. Đây là mã:

jQuery.extend(jQuery.expr[':'], { 
    focus: function(e){ return e == document.activeElement; } 
}); 

Vì vậy, giờ nó hoạt động như mong đợi.

Tuy nhiên, tôi đã gặp phải một số hành vi lạ trong Firefox 3.6.8 (có thể là lỗi trong FF?). Nếu tôi nhấp vào văn bản đầu vào trong khi trang được hiển thị và nếu tôi gọi là is(":focus") khi tải trang, tôi sẽ gặp lỗi từ trình duyệt, được báo cáo bởi FireBug và tập lệnh sẽ bị hỏng.

Để giải quyết vấn đề này, tôi đã bao quanh mã có khối try...catch, trả lại false do lỗi.Sử dụng nó nếu bạn muốn ngăn người dùng của mình gặp phải lỗi tương tự:

jQuery.extend(jQuery.expr[':'], { 
    focus: function(e){ 
     try{ return e == document.activeElement; } 
     catch(err){ return false; } 
    } 
}); 
1

Đây là cách ngắn gọn để thực hiện.

$(document.activeElement) 

hoặc để cắm nó vào ví dụ của bạn ..

if ($('form#contact input]')!=$(document.activeElement)) { ... } 
+0

Phần dưới cùng sẽ không bao giờ hoạt động vì chúng sẽ luôn là các bộ sưu tập jQuery khác nhau. – alex

11

jQuery 1.6 bây giờ có một :focus chọn chuyên dụng.

2

Tôi biết đây là một câu hỏi cũ, nhưng có thể giải pháp của tôi sẽ giúp một ai đó :)

từ didnt này làm việc cho tôi:

if ($(this)!=$(document.activeElement)) { ... } 

..were "này" được trả về từ mờ chức năng. Vì vậy, tôi đã làm điều này:

if ($(document.activeElement).attr("class") != "input_textbox"){ ... } 
+0

Giải pháp đầu tiên kết thúc tốt đẹp cả trong bộ sưu tập jQuery vì không có lý do gì, và nó cũng sẽ thất bại vì chúng sẽ là các đối tượng khác nhau. Cách thứ hai hiếm khi là một cách hay để kiểm tra xem một phần tử có phải là phần tử bạn khớp với một yếu tố nào đó vì các phần tử có thể có nhiều lớp hay không. – alex

-2
$('*:focus') 

(Necro ftw, nhưng vẫn có giá trị và hữu ích)

+0

Không nên yêu cầu '*'. – alex

+0

Necroing là tốt - câu hỏi và câu trả lời là vô tận, và thậm chí có một vài phù hiệu để trả lời một câu hỏi nhiều sau đó với một số điểm tốt, như Necromancer. _Tuy nhiên, _ Tôi đang giảm bớt điều này vì nó không cung cấp hướng dẫn về cách kiểm tra xem các yếu tố cụ thể có tập trung hay không. Bạn có thể thêm điều đó không? – doppelgreener

3

phiền rất khó để tìm một giải pháp cho vấn đề này xem xét các giải pháp thực sự là rất đơn giản:

if (document.activeElement == this) { 
 
    // has focus 
 
} 
 

 
if (document.activeElement != this) { 
 
    // does not have focus 
 
}

+0

Cảm ơn bạn đã cung cấp giải pháp JS gốc. – JoshJ

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