2009-08-13 2 views
83

У меня есть следующий код jQuery (аналогичный this question), который работает в Firefox и IE, но не работает (без ошибок, просто не работает) в Chrome и Safari. Любые идеи для обходного пути?Выбор текста в фокусе с использованием jQuery, не работающего в Safari и Chrome

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

Я хочу точное поведение в сафари iPad/iPhone. Это не работает в браузерах iPod/iPhone. любой ключ. Ниже принятый ответ предназначен только для настольных компьютеров Chrome/Safari. –

+5

Примечание: принятый ответ здесь разрешает половину проблемы. Это делает работу выбора, но затрудняет ее выбор с последующими щелчками. Лучшее решение можно найти здесь: http://stackoverflow.com/questions/3380458/looking-for-a-better-workaround-to-chrome-select-on-focus-bug – SDC

ответ

182

Это OnMouseUp событие, которое вызывает выбор, чтобы получить невыбранные, так что вам просто нужно добавить:

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

Вы, сэр, джентльмен и ученый. – user140550

+3

Подробнее об ошибке здесь: http://code.google.com/p/chromium/issues/detail?id=4505 – Rajat

+0

Как добиться того же, используя прототип? – tehfink

4

Это прекрасно подходит для элементов ввода = «текст». Какой элемент #souper_fancy?

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

это элемент типа = "текст" , Я попробовал $ («input [type = text]»). Все еще не работает с jQuery 1.3.2 в Safari. – user140550

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

Это лучший ответ, если вы пытаетесь выбрать текст в поле формы для приложения PhoneGap, работающего на Android. Это дает пользователю визуальное указание на то, что текст выбран, тогда как принятый ответ отсутствует. – BallisticPugh

1

Хотя это работает для выбора его в IE, Firefox, Chrome, Safari и Opera, он не позволит вам редактировать его, щелкнув второй раз в Firefox, Chrome и Safari. Не совсем уверен, но я думаю, что это может быть связано с тем, что эти три браузера повторно выдают фокусное событие, даже если поле уже имеет фокус, поэтому вы никогда не вставляете курсор (поскольку вы его снова выбираете), тогда как в IE и Opera, похоже, он этого не делает, поэтому фокусное событие больше не срабатывает, и, таким образом, курсор встает.

Я нашел лучшее исправление in this Stack post, которое не имеет этой проблемы и работает во всех браузерах.

1

Это должно работать также в хроме:

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

Пожалуйста, подумайте над добавлением конструктивной обратной связи о том, почему OP видит проблему, и ваше решение исправляет ее. –

2

Просто предупреждения по умолчанию на MouseUp вызывает выделение текста, чтобы быть включен в любое время. Событие MOUSEUP отвечает за очистку текста. Однако, предотвращая его поведение по умолчанию, вы не можете отменить выбор текста с помощью мыши.

Чтобы избежать этого и снова выберите текст, вы можете установить флаг на FOCUS, прочитать его из MOUSEUP и сбросить его, чтобы будущие события MOUSEUP работали должным образом.

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

Поскольку при использовании setTimeout происходит мерцание, существует другое решение, основанное на событиях. Таким образом, событие «focus» присоединяет событие «mouseup», а обработчик события снова отсоединяется.

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

Затем телеграфировать первое событие

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

setSelectionRange() Использование внутри обратного вызова для 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; 
    }); 
}); 

setSelectionRange() Используйте вместо select() так select() не работает в мобильном Safari (см. Programmatically selecting text in an input field on iOS devices (mobile Safari)).

Перед тем, как выбрать текст, необходимо подождать, используя requestAnimationFrame, иначе элемент не будет правильно прокручиваться после того, как клавиатура появится на iOS.

При использовании setSelectionRange() важно установить тип ввода text, в противном случае это может исключить исключения из Chrome (см. selectionStart/selectionEnd on input type="number" no longer allowed in Chrome).