Почему мою кнопку нужно нажать дважды, чтобы обработчик событий работал в первый раз, а затем только один раз? - PullRequest
6 голосов
/ 11 августа 2010

Я хочу, чтобы посетитель мог развернуть / свернуть некоторые разделы, и я использую:

<input onclick="return toggleDiv('xx')" 
       type="button" 
       class="button" 
       value="click here to expand/collapse"/>

и в I есть функция:

function toggleDiv(a){
  var e=document.getElementById(a);
  if(!e)return true;
  if(e.style.display=="none"){
    e.style.display="block"
  } else {
    e.style.display="none"
  }
  return true;
}

Первый разнажата кнопка, она не работает, последующие нажатия (на любую из кнопок) работают ОК.

Здесь есть связанный разговор: Для активации функции * необходимо дважды нажать кнопку1011 *

но я не понимаю ответ (слишком технический ;-), может кто-нибудь помочь объяснить это, пожалуйста?

Ответы [ 5 ]

10 голосов
/ 11 августа 2010

Первоначальный стиль вашего div'а 'xx' может вызывать некоторые проблемы ...

Объяснение

Допустим, у вас есть правило таблицы стилей, настроенное так, чтобы ваши div были изначально скрыты.Что-то вроде:

div { display: none }

(... где, конечно, селектор (div), вероятно, будет немного менее широким)

Это будет работать правильно, в этомстраница загрузится со всеми вашими div скрытыми элементами («свернутыми»).Однако в самих элементах нет фактического значения для свойства style.display - они просто наследуют значение из таблицы стилей.Таким образом, в вашем коде тест, который вы используете, чтобы проверить, скрыт ли элемент:

if(e.style.display=="none"){

... завершится неудачно, неправильно идентифицируя цель как видимую и вызывая свойство style.displayбыть установленным в "none" (который не имеет видимого эффекта, так как элемент уже был скрыт таблицей стилей).Затем следующий раз, когда кнопка будет нажата, значение, которое вы установили в последний раз, приведет к успешному выполнению текста, и ваша подпрограмма установит style.display в «block».

легкий способ исправить это - просто повернуть тест и проверить наличие "блока":

  if(e.style.display=="block"){
    e.style.display="none"
  } else {
    e.style.display="block"
  }

... однако, это развалится, если некоторые элементы настроены набыть изначально видимым: вы просто столкнетесь с той же проблемой в обратном порядке, при первом нажатии кнопки не будет никакого видимого эффекта.Для более надежного поведения вам нужно проверить стиль, который на самом деле активен для элемента:

function getStyle(el, name)
{
  // the way of the DOM
  if ( document.defaultView && document.defaultView.getComputedStyle )
  {
    var style = document.defaultView.getComputedStyle(el, null);
    if ( style )
      return style[name];
  }
  // IE-specific
  else if ( el.currentStyle )
    return el.currentStyle[name];

  return null;
}

function toggleDiv(a){
  var e=document.getElementById(a);
  if(!e)return true;
  if(getStyle(e, "display") == "none"){
    e.style.display="block"
  } else {
    e.style.display="none"
  }
  return true;
}

Здесь мы используем вспомогательную функцию getStyle() для извлечения активного значения в перекрестномПлатформенная манера.Смотри также: getComputedStyle(), currentStyle

2 голосов
/ 06 февраля 2012

Чтобы сохранить весь дополнительный код Javascript для получения стиля и т. Д., Простым исправлением этого будет добавление скрытого CSS к самому элементу.

<div class="yourclass" style="display:none;">content</div>

edit

Я решил объяснить свой ответ немного лучше.Я предполагаю, что вы не скрывали div, который хотели переключить по умолчанию, поэтому он был виден, однако при вызове e.style.display результат не будет none и не будет block, поскольку стильеще не было установлено.

Вместо этого вы извлекали пустую строку, которая означает, что при первом щелчке по ней выполнялся оператор else;для дисплея div при первом щелчке было установлено значение «Нет». Таким образом, при следующем щелчке значение будет извлечено как none, поэтому, конечно, оно изменится на block.

1 голос
/ 16 марта 2016

более легкая реализация как-то

var a=1;
function toggleDiv(xx){
  var e=document.getElementById(xx);

  if(a==1){
    e.style.display="block";a=0;
  } else {
    e.style.display="none";
  a=1;
  }

}
0 голосов
/ 11 февраля 2019

Простой ответ, который вы ищете, это добавить display:none; к встроенному стилю.Таким образом, когда вы посмотрите на

if (x.style.display == 'none')

, он вернет true!

0 голосов
/ 11 августа 2010

Нечто подобное может сработать для вас. Но поместите это в заголовок документа. функция загрузки окна важна, потому что DOM должен быть загружен, прежде чем вы можете возиться с полем ввода

<input id="divOpener" rel="xx" type="button" class="button" value="click here to expand/collapse"/>

и это

window.onload = function(){
            //  get input field from html
            var myInput = document.getElementById('divOpener');
            // add onclick handler
            myInput.onclick = function(){
               // if you really need to say which div in the document body, you can
               // add it to the rel or ref etc. attributes then get the value with
               // get attribute
               var myDiv = document.getElementById(this.getAttribute('rel'));
               if(!myDiv) return;
               if(myDiv.style.display=="none"){
                  myDiv.style.display="block";
               } else {
                 myDiv.style.display="none";
               }
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...