2

The purpose of this function is to make the second button appear after one second of the click on the first button. And make it disappear after a new click on the same button. But what happens is that after the second click the second button disappears and returns a second later, which is not required in the function. I checked it completely and it looks okay. But it is not working as it should.

function botao_home() {
  document.getElementById('mobile_index').style.display = 'block';
}
var onof1 = '0';

function showhide() {
  if (onof1 == '0') {
    setInterval(botao_home, 1000);
    onof1 = '1';
  } else {
    document.getElementById('mobile_index').style.display = 'none';
    onof1 = '0';
    /*Note that second click should only set the display property of id "mobile_index" to "none".
    But it is making the second button return, and this was not requested.*/
  }
}
#mobile_index {
  display: none
}

a {
  display: block;
  margin: 30px;
  padding: 40px;
  background: seagreen;
  color: palegreen;
  font-family: verdana, helvetica, arial, tahoma;
}
<div>
  <a style="cursor:pointer" onclick="showhide()">Show/Hide</a>
  <a id="mobile_index">P&aacute;gina Inicial</a>
</div>
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 2
    use boolean values `true` and `false` for binary conditions, not strings like `'0'` and `'1'`. – Barmar Jun 17 '17 at 00:27
  • Also using a boolean would be better for your if logic, as well as a setTimeout instead of a setInterval – Isac Jun 17 '17 at 00:28

4 Answers4

0

You can save your interval in a var and clear it.

var interval;
function showhide() {
 if (onof1=='0')
 {
  interval = setInterval(botao_home, 1000);
  onof1='1';
 }
 else
 {
  clearInterval(interval);
  document.getElementById('mobile_index').style.display = 'none';
  onof1='0';
  /*Note that second click should only set the display property of id "mobile_index" to "none".
  But it is making the second button return, and this was not requested.*/
 }
}
Kaenn
  • 76
  • 3
0

Use setTimeout, not setInterval. setInterval is for doing something periodically, setTimeout just does it once after a delay.

function botao_home() {
  document.getElementById('mobile_index').style.display = 'block';
}
var onof1 = false;

function showhide() {
  if (!onof1) {
    setTimeout(botao_home, 1000);
    onof1 = true;
  } else {
    document.getElementById('mobile_index').style.display = 'none';
    onof1 = false;
  }
}
#mobile_index {
  display: none
}

a {
  display: block;
  margin: 30px;
  padding: 40px;
  background: seagreen;
  color: palegreen;
  font-family: verdana, helvetica, arial, tahoma;
}
<div>
  <a style="cursor:pointer" onclick="showhide()">Show/Hide</a>
  <a id="mobile_index">P&aacute;gina Inicial</a>
</div>
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

You didn't say what you wanted to happen when the button was pushed again before the one second timer. The way this is written the timer will be reset with each click before the second link is shown.

Instead of setting properties directly I'm toggling classes.

When you click the link it checks for the timer, cancels it if set and sets a new timer. If the link is shown then it toggles the classes. I set the shown variable when I add the classes not when the click happens. That way multiple clicks don't leave mobileIndexShown in an invalid state.

Of course before you should really look at wrapping this in its own container so you don't have to leave your timer and shown flag in the global name space.

    var mobileIndexShown = false;
    var timerSet;
    
    function showhide() {
        if (timerSet) {
            clearTimeout(timerSet);
        }
    
        if (!mobileIndexShown) {        
            timerSet = setTimeout(toggleMobileIndex, 1000);
        } else {
            toggleMobileIndex();
        }
    }
    
    function toggleMobileIndex()
    {
        var mobileIndex = document.getElementById('mobile_index');
        timerSet = false;
    
        if (mobileIndex.className === 'DisplayBlock') {
            mobileIndex.className = 'DisplayNone';
            mobileIndexShown = false;
        } else {
            mobileIndex.className = 'DisplayBlock';
            mobileIndexShown = true;
        }
    
    }
    .DisplayBlock {
      display: block;
    }

    .DisplayNone {
      display: none
    }

    a {
        display: block;
        margin: 30px;
        padding: 40px;
        background: seagreen;
        color: palegreen;
        font-family: verdana, helvetica, arial, tahoma;
    }
    
    <div>
        <a style="cursor:pointer" onclick="showhide()">Show/Hide</a>
        <a id="mobile_index" class="DisplayNone">P&aacute;gina Inicial</a>
    </div>
Russell
  • 476
  • 2
  • 10
0

Delayed CSS animation + JS classList

This answer uses CSS visibility instead of display which has some layout considerations which may need to be addressed.

The JavaScript toggles the class .show on each click of the first <a> button. If the class is already present on the element, it is removed, and if it's not present it is added.

When .show is added, a CSS animation with a 1 second delay is started. After the 1 second delay, the animation (with no duration) is played, setting the visibility to visible at the end. The animation-fill-mode: forwards captures the state of the visibility and maintains it on the element.

When .show is removed, the visibility returns to the CSS's default of hidden.

function showhide() {
    document.getElementById( 'mobile_index' ).classList.toggle( 'show' );
}
#mobile_index{
    visibility: hidden;
}
#mobile_index.show {
    animation-name: delayed_show;
 animation-delay: 1s;
 animation-fill-mode: forwards;
}
@keyframes delayed_show {
    0% { visibility: hidden; }
    100% { visibility: visible; }
}
a {
  display: block;
  user-select: none;
  margin: 30px;
  padding: 40px;
  background: seagreen;
  color: palegreen;
  font-family: verdana, helvetica, arial, tahoma;
}
<div>
    <a style="cursor:pointer" onclick="showhide()">Show/Hide</a>
    <a id="mobile_index">P&aacute;gina Inicial</a>
</div>
Fred Gandt
  • 4,217
  • 2
  • 33
  • 41