Chọn văn bản trên tiêu điểm bằng jQuery không hoạt động trong Safari và Chrome


85

Tôi có mã jQuery sau (tương tự như câu hỏi này ) hoạt động trong Firefox và IE, nhưng không thành công (không có lỗi, chỉ là không hoạt động) trong Chrome và Safari. Bất kỳ ý tưởng cho một cách giải quyết?

$("#souper_fancy").focus(function() { $(this).select() });

Tôi muốn hành vi chính xác trong safari của iPad / iPhone. Điều này không hoạt động trong trình duyệt iPod / iPhone. bất kỳ manh mối nào. Câu trả lời được chấp nhận dưới đây chỉ dành cho Chrome / safari dựa trên Máy tính để bàn.
Anand

5
Lưu ý: Câu trả lời được chấp nhận ở đây chỉ giải quyết được một nửa vấn đề. Nó làm cho lựa chọn hoạt động, nhưng gây khó khăn khi bỏ chọn nó với những lần nhấp tiếp theo. Một giải pháp tốt hơn có thể được tìm thấy ở đây: stackoverflow.com/questions/3380458/...
SDC

Câu trả lời:


188

Đó là sự kiện onmouseup khiến vùng chọn không được chọn, vì vậy bạn chỉ cần thêm:

$("#souper_fancy").mouseup(function(e){
    e.preventDefault();
});

3
Tham khảo thêm về lỗi tại đây: code.google.com/p/chromium/issues/detail?id=4505
Rajat

Làm thế nào để đạt được điều tương tự bằng cách sử dụng Prototype?
tehfink

Bạn cũng có thể thử ràng buộc với sự kiện 'nhấp chuột' và tránh phải thực hiện hai ràng buộc.
xấu xí

@uglymunky Tùy thuộc vào những gì bạn đang làm, liên kết với sự kiện nhấp chuột sẽ không hoạt động trong mọi trường hợp - xét cho cùng, có các phương tiện khác để chọn một trường nhập liệu hơn là nhấp vào nó và bạn cũng muốn những trường đó hoạt động (ví dụ: tab vào nó)
Tacroy

2
Tôi muốn hành vi chính xác trong safari của iPad / iPhone. Điều này không hoạt động trong trình duyệt iPod / iPhone. bất kỳ manh mối nào.
Anand

25
$('#randomfield').focus(function(event) {
    setTimeout(function() {$('#randomfield').select();}, 0);
});

3
Đây là câu trả lời tốt nhất nếu bạn đang cố gắng chọn văn bản trong trường biểu mẫu cho ứng dụng Bản đồ điện thoại chạy trên Android. Điều này cung cấp một dấu hiệu trực quan cho người dùng rằng văn bản được chọn, trong khi câu trả lời được chấp nhận thì không.
BallisticPugh

4

Điều này hoạt động tốt cho các phần tử input type = "text". #Souper_fancy là loại phần tử nào?

$("#souper_fancy").focus(function() {
    $(this).select();
});

đó là một phần tử type = "text". Tôi cũng đã thử $ ("input [type = text]"). Vẫn không hoạt động với jQuery 1.3.2 trong Safari.
user140550

3

Việc chỉ ngăn mặc định khi di chuột lên sẽ khiến vùng chọn văn bản luôn BẬT. Sự kiện MOUSEUP có trách nhiệm xóa lựa chọn văn bản. Tuy nhiên, bằng cách ngăn hành vi mặc định của nó, bạn không thể bỏ chọn văn bản bằng chuột.

Để tránh điều đó và làm cho lựa chọn văn bản hoạt động trở lại, bạn có thể đặt cờ trên FOCUS, đọc nó từ MOUSEUP và đặt lại nó để các sự kiện MOUSEUP trong tương lai sẽ hoạt động như mong đợi.

$("#souper_fancy").focus(function() {
    $(this).select();

    //set flag for preventing MOUSEUP event....
    $this.data("preventMouseUp", true);
});

$("#souper_fancy").mouseup(function(e) {
    var preventEvent = $this.data("preventMouseUp");

    //only prevent default if the flag is TRUE
    if (preventEvent) {
        e.preventDefault();
    }

    //reset flag so MOUSEUP event deselect the text
    $this.data("preventMouseUp", false);
});

1

Mặc dù điều này hoạt động để chọn nó trong IE, Firefox, Chrome, Safari và Opera, nó sẽ không cho phép bạn chỉnh sửa nó bằng cách nhấp vào lần thứ hai trong Firefox, Chrome và Safari. Không hoàn toàn chắc chắn, nhưng tôi nghĩ điều này có thể là do 3 trình duyệt đó phát hành lại sự kiện tiêu điểm mặc dù trường đã có tiêu điểm do đó không bao giờ cho phép bạn thực sự chèn con trỏ (vì bạn đang chọn lại), trong khi trong IE và Opera có vẻ như nó không làm điều đó nên sự kiện tiêu điểm không được kích hoạt trở lại và do đó con trỏ được chèn vào.

Tôi đã tìm thấy một bản sửa lỗi tốt hơn trong bài đăng Stack này không có vấn đề đó và hoạt động trên tất cả các trình duyệt.


1

Điều này cũng sẽ hoạt động trong chrome:

$("#souper_fancy").focus(function() {
    var tempSouper = $(this);
    setTimeout(function(){
        tempSouper.select();
    },100);
});

Vui lòng xem xét thêm phản hồi mang tính xây dựng về lý do OP nhận thấy sự cố và giải pháp của bạn khắc phục nó.
Mirko Adari

1

Vì có hiện tượng nhấp nháy khi bạn sử dụng setTimeout, nên có một giải pháp dựa trên sự kiện khác. Bằng cách này, sự kiện 'tiêu điểm' sẽ đính kèm sự kiện 'mouseup' và trình xử lý sự kiện lại tự tách ra.

    function selectAllOnFocus(e) {
    if (e.type == "mouseup") { // Prevent default and detach the handler
        console.debug("Mouse is up. Preventing default.");
        e.preventDefault();
        $(e.target).off('mouseup', selectAllOnFocus);
        return;
    }
    $(e.target).select();
    console.debug("Selecting all text");
    $(e.target).on('mouseup', selectAllOnFocus);
}

Sau đó chuyển sự kiện đầu tiên

    $('.varquantity').on('focus', selectAllOnFocus);

1

Sử dụng setSelectionRange()bên trong một cuộc gọi lại tới requestAnimationFrame():

$(document).on('focus', '._selectTextOnFocus', (e) => {
    var input = e.currentTarget;
    var initialType = e.currentTarget.type;

    requestAnimationFrame(() => {
        // input.select() is not supported on iOS
        // If setSelectionRange is use on a number input in Chrome it throws an exception,
        // so here we switch to type text first.
        input.type = "text";
        input.setSelectionRange(0, Number.MAX_SAFE_INTEGER || 9999);
        input.type = initialType;
    });
});

Sử dụng setSelectionRange()thay vì select()kể từ khi select()không làm việc trong điện thoại di động Safari (xem Lập trình chọn văn bản trong một lĩnh vực đầu vào trên các thiết bị iOS (di động Safari) ).

Cần phải đợi sử dụng requestAnimationFrametrước khi chọn văn bản, nếu không phần tử không được cuộn đúng cách để xem sau khi bàn phím xuất hiện trên iOS.

Khi sử dụng, setSelectionRange()điều quan trọng là phải đặt loại đầu vào thành text, nếu không nó có thể tạo ra các ngoại lệ trên Chrome (xem selectStart / selectionEnd on input type = "number" không còn được phép trong Chrome ).


0

Nếu ai đó gặp lại vấn đề này, tôi có ở đây một giải pháp JS thuần túy (tại thời điểm này) hoạt động trên tất cả các trình duyệt bao gồm. di động

<input type="text" value="Hello world..." onFocus="window.setTimeout(() => this.select());">

(không có setTimeout () nó không hoạt động trên Safari, Safari di động và MS Edge)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.