最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - onblur event is not firing - Stack Overflow

programmeradmin1浏览0评论

I need to fire onblur event when I click outside "aside panel", in order to make the panel close if user clicks outside navigation panel.
Though I'm using React JS - but for simplicity I've written example in pure JavaScript. Lately I've written something similar and everything works fine, but in this case it's not working, may be because of position fixed.

var d = document.getElementById("fname");

d.addEventListener("blur", myFunction);

function myFunction() {
  alert("Input field lost focus.");
}
var state = true;

function myFunction2() {
  state = !state;
  if (state) {
    d.className = "header__aside";
  } else {
    d.className += " header__aside--open";
  }

}
.main {
  background-color: violet;
  padding: 50px;
}

.header__aside {
  background-color: #cfcfcf;
  box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
  font-size: 1.2rem;
  height: 100%;
  opacity: 0.9;
  position: fixed;
  right: -30%;
  top: 0;
  transition: right 0.5s ease-out;
  width: 30%;
  z-index: 10;
}

.header__aside--open {
  right: 0;
}
<p class='main'>This example</p>
<button type="button" onClick="myFunction2()">
&#9776;
</button>
<div class="header__aside" id="fname">
  <div class="aside-nav">
    <div class="aside-nav__header">
      <button type="button" class="aside-nav__header-button" onClick="myFunction2()">x</button>
    </div>
    <nav class="nav nav__aside">
      <a class="nav__aside-link active" aria-current="true" href="/">Main</a>
    </nav>
  </div>
</div>

I need to fire onblur event when I click outside "aside panel", in order to make the panel close if user clicks outside navigation panel.
Though I'm using React JS - but for simplicity I've written example in pure JavaScript. Lately I've written something similar and everything works fine, but in this case it's not working, may be because of position fixed.

var d = document.getElementById("fname");

d.addEventListener("blur", myFunction);

function myFunction() {
  alert("Input field lost focus.");
}
var state = true;

function myFunction2() {
  state = !state;
  if (state) {
    d.className = "header__aside";
  } else {
    d.className += " header__aside--open";
  }

}
.main {
  background-color: violet;
  padding: 50px;
}

.header__aside {
  background-color: #cfcfcf;
  box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
  font-size: 1.2rem;
  height: 100%;
  opacity: 0.9;
  position: fixed;
  right: -30%;
  top: 0;
  transition: right 0.5s ease-out;
  width: 30%;
  z-index: 10;
}

.header__aside--open {
  right: 0;
}
<p class='main'>This example</p>
<button type="button" onClick="myFunction2()">
&#9776;
</button>
<div class="header__aside" id="fname">
  <div class="aside-nav">
    <div class="aside-nav__header">
      <button type="button" class="aside-nav__header-button" onClick="myFunction2()">x</button>
    </div>
    <nav class="nav nav__aside">
      <a class="nav__aside-link active" aria-current="true" href="/">Main</a>
    </nav>
  </div>
</div>

Share Improve this question asked Nov 15, 2017 at 12:59 Taras YaremkivTaras Yaremkiv 3,6008 gold badges33 silver badges56 bronze badges 6
  • You can't attach onblur event on a div, AFAIK it's generally used with inputs and form elements. – cнŝdk Commented Nov 15, 2017 at 13:01
  • @chsdk Weird but in React it's working 100% comething like this: <div className="header__bottom" onBlur={this.handleClickOutside}> – Taras Yaremkiv Commented Nov 15, 2017 at 13:03
  • 1 @chsdk Ok I'll rewrite question using React JS – Taras Yaremkiv Commented Nov 15, 2017 at 13:10
  • But I think what you need is a click event and check if the taget is not your div. – cнŝdk Commented Nov 15, 2017 at 13:16
  • @chsdk I've took example from detect-click-outside-react-component question. It's not that simple because I detect if user clicks outside sidepanel area which is dynamic – Taras Yaremkiv Commented Nov 15, 2017 at 13:23
 |  Show 1 more comment

3 Answers 3

Reset to default 14

To have Onblur on an element it should receive focus first, Div elements don't receive focus by default. You can add tabindex="0"

<div tabindex="0" ....

Thanks to Emil, for react you can use

tabIndex={0}

You will have to set a tabindex on the div and manually focus it to get the blur handler invoked

var d = document.getElementById("fname");

d.addEventListener("blur", myFunction);

function myFunction() {
  alert("Input field lost focus.");
}
var state = true;

function myFunction2() {
  state = !state;
  d.focus();
  if (state) {
    d.className = "header__aside";
  } else {
    d.className += " header__aside--open";
  }

}
.main {
  background-color: violet;
  padding: 50px;
}

.header__aside {
  background-color: #cfcfcf;
  box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
  font-size: 1.2rem;
  height: 100%;
  opacity: 0.9;
  position: fixed;
  right: -30%;
  top: 0;
  transition: right 0.5s ease-out;
  width: 30%;
  z-index: 10;
}

.header__aside--open {
  right: 0;
}
<p class='main'>This example</p>
<button type="button" onClick="myFunction2()">
&#9776;
</button>
<div class="header__aside" id="fname" tabindex="0">
  <div class="aside-nav">
    <div class="aside-nav__header">
      <button type="button" class="aside-nav__header-button" onClick="myFunction2()">x</button>
    </div>
    <nav class="nav nav__aside">
      <a class="nav__aside-link active" aria-current="true" href="/">Main</a>
    </nav>
  </div>
</div>

Add tabindex=0 to the panel-html and focus() to the JS opening the panel:

<div id=panel tabindex=0></div>

document.getElementById('panel').onclick = function(){ 
  document.getElementById('panel').style.display = 'block';
  document.getElementById('panel').focus();
  document.getElementById('panel').onblur = function(){ 
    document.getElementById('panel').style.display = 'none';
  }
}
发布评论

评论列表(0)

  1. 暂无评论