2009-08-13 12 views
83

Mam następujący kod jQuery (podobny do this question), który działa w przeglądarkach Firefox i IE, ale kończy się niepowodzeniem (brak błędów, po prostu nie działa) w przeglądarce Chrome i Safari. Jakieś pomysły na obejście tego problemu?Wybieranie tekstu skupienia za pomocą jQuery nie działa w przeglądarce Safari i przeglądarce Chrome Chrome i

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

Chcę zachować dokładne zachowanie w safari na iPadzie/iPhonie. To nie działa w przeglądarkach urządzeń iPod/iPhone. jakakolwiek wskazówka. Poniżej akceptowana odpowiedź dotyczy tylko Chrome/Safari na komputery. –

+5

Uwaga: Zaakceptowana tutaj odpowiedź rozwiązuje tylko połowę problemu. Wykonuje wybraną pracę, ale utrudnia jej usunięcie przy kolejnych kliknięciach. Lepsze rozwiązanie można znaleźć tutaj: http://stackoverflow.com/questions/3380458/looking-for-a-better-workaround-to-chrome-select-on-focus-bug – SDC

Odpowiedz

182

To onmouseup zdarzenie, które powoduje wybór dostać zaznaczone, więc wystarczy dodać:

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

Ty jesteś dżentelmenem i uczonym. – user140550

+3

Więcej informacji o błędzie tutaj: http://code.google.com/p/chromium/issues/detail?id=4505 – Rajat

+0

Jak osiągnąć to samo za pomocą prototypu? – tehfink

4

Działa to dobrze dla elementów typu input = "text". Jakiego rodzaju elementem jest #souper_fancy?

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

to element type = "text" . Próbowałem również $ ("input [type = text]"). Nadal nie działa z jQuery 1.3.2 w Safari. – user140550

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

To jest najlepsza odpowiedź, jeśli próbujesz wybrać tekst w polu formularza dla aplikacji PhoneGap działającej na systemie Android. Daje to wizualne wskazanie użytkownikowi, że tekst jest wybrany, podczas gdy zaakceptowana odpowiedź nie. – BallisticPugh

1

Chociaż to działa na wybranie go w IE, Firefox, Chrome, Safari i Opera nie pozwolą ci go edytować, klikając po raz drugi w przeglądarce Firefox, Chrome i Safari. Nie jestem do końca pewien, ale myślę, że może to wynikać z tych 3 przeglądarek, które ponownie emitują fokus, mimo że pole ma już fokus, więc nigdy nie pozwala ci wstawić kursora (ponieważ wybierasz go ponownie), podczas gdy w IE i Opera wydaje się, że nie robi tego, więc fokus nie został ponownie uruchomiony i w ten sposób kursor zostanie wstawiony.

Znalazłem lepszą poprawkę in this Stack post, która nie ma tego problemu i działa we wszystkich przeglądarkach.

1

To powinno działać także w chrome:

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

Należy rozważyć dodanie konstruktywnej informacji zwrotnej na temat tego, dlaczego OP widzi problem, a rozwiązanie go rozwiązuje. –

2

Wystarczy zapobiegania domyślna mouseUp powoduje zaznaczenie tekstu, aby być przez cały czas. Zdarzenie MOUSEUP jest odpowiedzialne za wyczyszczenie zaznaczenia tekstu. Jednak uniemożliwiając zachowanie domyślne, nie można odznaczyć tekstu za pomocą myszy.

Aby tego uniknąć i ponownie wybierz tekst, możesz ustawić flagę na FOCUS, odczytać z MOUSEUP i zresetować, aby przyszłe zdarzenia MOUSEUP działały zgodnie z oczekiwaniami.

$("#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

Ponieważ podczas korzystania z funkcji setTimeout występuje migotanie, dostępne jest inne rozwiązanie oparte na zdarzeniach. W ten sposób zdarzenie "focus" dołącza zdarzenie "mouseup", a moduł obsługi zdarzeń odłączy się ponownie.

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); 
} 

Następnie drut pierwsze zdarzenie

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

Zastosowanie setSelectionRange() wewnątrz wywołania zwrotnego do 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; 
    }); 
}); 

Zastosowanie setSelectionRange() zamiast select()select() ponieważ nie działa w mobilnym Safari (patrz Programmatically selecting text in an input field on iOS devices (mobile Safari)).

Przed zaznaczeniem tekstu należy poczekać, używając requestAnimationFrame, w przeciwnym razie element nie zostanie poprawnie przewinięty do widoku po pojawieniu się klawiatury w systemie iOS.

Podczas korzystania z setSelectionRange() ważne jest, aby ustawić typ wejścia na text, w przeciwnym razie może on generować wyjątki w Chrome (patrz selectionStart/selectionEnd on input type="number" no longer allowed in Chrome).