Google Chrome: фокус проблемы с полосой прокрутки - PullRequest
6 голосов
/ 28 августа 2009

Я использую jQuery 1.3.2.

В форме есть поле ввода. Нажатие на поле ввода открывает div как выпадающий список. Div содержит список элементов. Поскольку размер списка велик, в div есть вертикальная полоса прокрутки. alt text

Чтобы закрыть раскрывающийся список при щелчке снаружи, в поле ввода есть событие размытия.

Теперь проблема:

В chrome (2.0.172) при нажатии на полосу прокрутки поле ввода теряет фокус. А теперь, если вы нажмете снаружи, то выпадающий список не закроется (так как ввод уже потерял фокус при нажатии на полосу прокрутки)

В Firefox (3.5), IE (8), opera (9.64), safari () при нажатии на полосу прокрутки поле ввода не теряет фокус. Следовательно, когда вы щелкаете снаружи (после нажатия на полосу прокрутки), раскрывающийся список закрывается. Это ожидаемое поведение.

Так что в chrome один раз будет нажата полоса прокрутки, а затем, если я нажму снаружи, выпадающий список не закроется. Как я могу исправить эту проблему с Chrome.

Ответы [ 8 ]

4 голосов
/ 26 сентября 2009

Ну, у меня была та же проблема с моим выпадающим списком. Я спросил разработчиков Chrome относительно этой проблемы, они сказали, что это ошибка , которая не будет исправлена ​​в ближайшем будущем из-за того, что «о ней не сообщали многие люди, и это исправление не тривиально» , Итак, давайте посмотрим правде в глаза: эта ошибка останется еще как минимум на год.

Хотя для этого конкретного случая (выпадающего списка) есть обходной путь. Хитрость в том, что при одном щелчке на полосе прокрутки событие «мыши вниз» приходит к элементу владельца этой полосы прокрутки. Мы можем использовать этот факт, чтобы установить флаг и проверить его в обработчике «onblur». Вот объяснение:

<input id="search_ctrl">
<div id="dropdown_wrap" style="overflow:auto;max-height:30px">
  <div id="dropdown_rows">
    <span>row 1</span>
    <span>row 2</span>
    <span>row 2</span>
  </div>
</div>

div "dropdown_wrap" получит вертикальную полосу прокрутки, поскольку ее содержимое не соответствует фиксированной высоте. Как только мы получим щелчок, мы почти уверены, что полоса прокрутки была нажата, и фокус будет снят. Теперь немного кода, как с этим справиться:

search_ctrl.onfocus = function() {
  search_has_focus = true
}

search_ctrl.onblur = function() {
  search_has_focus = false
  if (!keep_focus) {
    // hide dropdown
  } else {
    keep_focus = false;
    search_ctrl.focus();
  }
}

dropdow_wrap.onclick = function() {
  if (isChrome()) {
    keep_focus = search_has_focus;
  }
}

Вот и все. Нам не нужны хаки для FF, поэтому есть проверка для браузера. В Chrome мы обнаруживаем щелчок на полосе прокрутки, разрешаем размытие фокуса, не закрывая список, а затем немедленно возвращаем фокус обратно к элементу управления вводом. Конечно, если у нас есть некоторая логика для «search_ctrl.onfocus», она также должна быть изменена. Обратите внимание, что нам нужно проверить, был ли у search_ctrl фокус, чтобы избежать двойных щелчков.

Вы можете догадаться, что лучшей идеей может быть отмена события onblur, но это не сработает в Chrome. Не уверен, что это ошибка или особенность.

P.S. «dropdown_wrap» не должен иметь никаких отступов или границ, в противном случае пользователь может щелкнуть эти области, и мы будем рассматривать это как нажатие полосы прокрутки.

2 голосов
/ 18 января 2013

Я не мог заставить эти ответы работать, возможно, потому что они с 2009 года. Я только что имел дело с этим, я думаю, что ihsoft находится на правильном пути, но немного тяжело.

с двумя функциями

onMouseDown() {
    lastClickWasDropdown=true;
}
onBlur() {
    if (lastClickWasDropdown) {
        lastClickWasDropdown = false;
        box.focus();
    } else {
        box.close();
    }
}

Хитрость в том, как вы связываете элементы. Событие onMouseDown должно находиться в элементе «container», который содержит все, что будет щелкнуто (т. Е. Текстовое поле, стрелку раскрывающегося списка, а также раскрывающийся список и его полосу прокрутки). Событие Blur (или в jQuery событие focusout) должно быть привязано непосредственно к текстовому полю.

Проверено и работает!

1 голос
/ 07 февраля 2012

Я столкнулся с той же ситуацией / проблемой, и я протестировал решение от "ihsoft", но у него есть некоторые проблемы. Так что я работал над альтернативой для этого и сделал только один, похожий на «ihsoft», но тот, который работает. вот мое решение:

var hide_dropdownlist=true;

search_ctrl.onblur = function() {

  search_has_focus = false
  if (hide_dropdownlist) {
    // hide dropdown
  } else {
    hide_dropdownlist = true;
    search_ctrl.focus();
  }
}

dropdow_wrap.onmouseover = function() {
    hide_dropdownlist=false;
}
dropdow_wrap.onmouseoout = function() {
    hide_dropdownlist=true;
}

Надеюсь, это кому-нибудь поможет.

1 голос
/ 28 августа 2009

Раньше я тоже сталкивался с такой ситуацией, и этим я и занимался.

$('html').click(function() {
    hasFocus = 0;
    hideResults();
});

и в поле ввода я сделаю это

$('input').click()
{
    event.stopPropagation();

}

Так что это закроет выпадающий список, если щелкнуть где-нибудь за пределами div (даже полосы прокрутки). Но я подумал, что если кто-то сможет предложить более логичное решение.

0 голосов
/ 19 ноября 2010

Я решил это, выполнив следующее:

# my_container - это контейнер с правилом CSS "overflow: auto"

$('#my_container')  
    .mouseenter(function(){  
    //  alert('ctr in!');  
    mouse_in_container = true;  
    })  

    .mouseleave(function(){   
     //  alert('ctr out!');  
     mouse_in_container = false;  
    });  

А потом:

$('input').blur(function(){
  if(mouse_in_container)
    return;
  ... Normal code for blur event ...
});

Когда я выбираю элемент в раскрывающемся списке, я переписываю код следующим образом:

        (>> ADDED THIS) mouse_in_container=false;
        $('input').attr('active', false); // to blur input
        $('#my_container').hide();
0 голосов
/ 28 января 2010

вместо того, чтобы обнаруживать размытие, обнаружите document.body или щелчок окна и захватите точку мыши. определить, находится ли эта точка мыши за пределами поля меню. Presto, вы обнаружили, когда они щелкнули за пределами поля!

0 голосов
/ 28 августа 2009

Мне любопытно ...
Вы используете последнюю версию каждого браузера, почему бы вам не попробовать ее в Chrome 4.0.202?

0 голосов
/ 28 августа 2009

Не могли бы вы установить событие размытия так, чтобы оно срабатывало и в выпадающем меню? Таким образом, когда вход или выпадающий теряет фокус, он исчезает ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...