【问题标题】:jQuery e.target with a $(document).on("click", function(e)带有 $(document).on("click", function(e) 的 jQuery e.target
【发布时间】:2019-01-17 11:02:31
【问题描述】:

当用户点击document 上的任何位置时,我有一个关闭.modal 的功能,除了模式。

$(document).on("click", function(e) {
  if (
    $(".apple-modal, .icon-modal").hasClass("active") &&
    !$(".modal, .modal *, .button").is(e.target)
  ) {
    $(".modal").removeClass("active");
  }
});

问题是fontawesome 图标干扰了打开模式的.button 目标,点击区域只是.button 而不是嵌套在里面的任何东西(图标)。

如何更改功能,以便即使单击图标也会打开模式,然后在用户单击离开时丢失它的 .active 类?

$("[data-close]").click(function(e) {
  const dataClose = $(this).attr("data-close");
  const elem = $('[data-id="' + dataClose + '"]').length ?
    $('[data-id="' + dataClose + '"]') :
    $(dataClose);
  if (elem.hasClass("active") && elem.is(":visible")) {
    elem.removeClass("active");
    e.stopImmediatePropagation();
  }
});
$(".button").on("click", function() {
  const id = $(this).prop("id");
  $(".modal").each(function() {
    $(this).toggleClass("active", $(this).data("id") == id);
  });
});
$(document).on("click", function(e) {
  if (
    $(".apple-modal, .icon-modal").hasClass("active") &&
    !$(".modal, .modal *, .button").is(e.target)
  ) {
    $(".modal").removeClass("active");
  }
});
.buttons {
  display: flex;
  align-items: center;
}

.button {
  height: 30px;
  cursor: pointer;
  border: 2px solid;
  padding: 1rem;
  font-size: 28px;
}

#icon {
  color: silver;
}

.header {
  height: 15px;
  background: #eee;
}

.modal {
  position: fixed;
  top: 72px;
  right: 15px;
  z-index: 6;
  opacity: 0;
  visibility: hidden;
  transform: scale(0.5);
  transform-origin: top right;
  transition: 0.15s;
  box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
}

.modal:after {
  content: "";
  width: 15px;
  height: 15px;
  background: inherit;
  position: absolute;
  background: #eee;
  top: -6px;
  right: 8px;
  opacity: 0;
  visibility: hidden;
  transform: rotate(45deg) scale(0.5);
  transition: 0.15s;
}

.modal.active {
  opacity: 1;
  visibility: visible;
  transform: scale(1);
}

.modal.active:after {
  opacity: 1;
  visibility: visible;
  transform: rotate(45deg) scale(1);
}
<script src="https://pro.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="buttons">
  <img src="https://www.dignitasteam.com/wp-content/uploads/2015/09/3050613-inline-i-2-googles-new-logo-copy.png" class="button" id="google" data-close="google" />
  <img src="https://www.arabianbusiness.com/sites/default/files/styles/full_img/public/images/2017/01/17/apple-logo-rainbow.jpg" class="button" id="apple" data-close="apple" />
  <div class="button" id="icon" data-close="icon">
    <i class="fas fa-bell"></i>
  </div>
</div>
<div class="modal" data-id="google">
  <div class="header">Google</div>
  <ul>
    <li>
      First</li>
    <li>
      Second</li>
    <li>
      Third</li>
  </ul>
</div>
<div class="modal apple-modal" data-id="apple">
  <div class="header">Apple</div>
  <ul>
    <li>
      First</li>
    <li>
      Second</li>
    <li>
      Third</li>
  </ul>
</div>
<div class="modal icon-modal" data-id="icon">
  <div class="header">Icon</div>
  <ul>
    <li>
      First</li>
    <li>
      Second</li>
    <li>
      Third</li>
  </ul>
</div>

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    目前还不是很清楚你到底想做什么。 Font Awesome 不会中断点击事件。我也会考虑使用 jQuery UI。

    考虑下面的代码。

    $(function() {
      $("[data-close]").click(function(e) {
        const dataClose = $(this).attr("data-close");
        const elem = $('[data-id="' + dataClose + '"]').length ?
          $('[data-id="' + dataClose + '"]') :
          $(dataClose);
        if (elem.hasClass("active") && elem.is(":visible")) {
          elem.removeClass("active");
          e.stopImmediatePropagation();
        }
      });
    
      $("body").not(".active").click(function(e) {
        console.log("body click");
        $(".active").removeClass("active");
      });
    
      $(".button").click(function(e) {
        var el = $(".modal[data-id='" + $(this).attr("id") + "']");
        console.log($(this).attr("id") + " clicked, remove class 'active' from all. Add 'active' to ", el);
        $(".active").removeClass("active");
        el.addClass("active");
        console.log(el);
        e.stopPropagation();
      });
    });
    .buttons {
      display: flex;
      align-items: center;
    }
    
    .button {
      height: 30px;
      cursor: pointer;
      border: 2px solid;
      padding: 1rem;
      font-size: 28px;
    }
    
    #icon {
      color: silver;
    }
    
    .header {
      height: 15px;
      background: #eee;
    }
    
    .modal {
      position: fixed;
      top: 72px;
      right: 15px;
      z-index: 6;
      opacity: 0;
      visibility: hidden;
      transform: scale(0.5);
      transform-origin: top right;
      transition: 0.15s;
      box-shadow: 0 1.5px 4px rgba(0, 0, 0, 0.24), 0 1.5px 6px rgba(0, 0, 0, 0.12);
    }
    
    .modal:after {
      content: "";
      width: 15px;
      height: 15px;
      background: inherit;
      position: absolute;
      background: #eee;
      top: -6px;
      right: 8px;
      opacity: 0;
      visibility: hidden;
      transform: rotate(45deg) scale(0.5);
      transition: 0.15s;
    }
    
    .modal.active {
      opacity: 1;
      visibility: visible;
      transform: scale(1);
    }
    
    .modal.active:after {
      opacity: 1;
      visibility: visible;
      transform: rotate(45deg) scale(1);
    }
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="buttons">
      <img src="https://www.dignitasteam.com/wp-content/uploads/2015/09/3050613-inline-i-2-googles-new-logo-copy.png" class="button" id="google" data-close="google" />
      <img src="https://www.arabianbusiness.com/sites/default/files/styles/full_img/public/images/2017/01/17/apple-logo-rainbow.jpg" class="button" id="apple" data-close="apple" />
      <div class="button" id="icon" data-close="icon">
        <i class="fas fa-bell"></i>
      </div>
    </div>
    
    <div class="modal" data-id="google">
      <div class="header">Google</div>
      <ul>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
      </ul>
    </div>
    <div class="modal apple-modal" data-id="apple">
      <div class="header">Apple</div>
      <ul>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
      </ul>
    </div>
    <div class="modal" data-id="icon">
      <div class="header">Icon</div>
      <ul>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
      </ul>
    </div>

    你可以在这里看到我已经调整了click 回调。如果您不创建动态内容,我会使用 .click() 而不是 .on()

    在这种情况下,最好将active 类从所有类中删除,然后将其添加到特定的一个元素中。 .toggleClass() 会这样做,但根据脚本的状态,您可能会得到不同的结果或意外的结果。

    使用正确的选择器也有很大帮助。由于我们的目标是具有data-id 属性的特定.modal,因此我们可以使用$(".modal[data-id='icon']") 作为选择器来获取该特定元素。

    希望对您有所帮助。

    【讨论】:

    • 问题是现在如果我点击离开,图标模式不会像我打开苹果模式并点击离开时那样消失。我无法单击图标本身以打开图标模式,然后能够单击离开并像苹果一样关闭该模式
    • @KyleUnderhill 查看更新的代码。同样,可以考虑使用 jQuery UI 对话框。
    • 更好,但我有 $(".apple-modal, .icon-modal").hasClass("active") && !$(".modal, .modal *, .button" ).is(e.target) ) { $(".modal").removeClass("active");这样谷歌模式(以及任何其他不是苹果和图标的模式)不会在点击离开时关闭。这个想法是当点击离开时一些关闭并且其他模式保持打开,除非再次按下按钮。我的问题是,对于点击关闭的模式,我无法点击图标打开模式,只有目标按钮......
    • @KyleUnderhill 我无法理解您尝试使用的逻辑。也许你可以自己解决这个问题。您的帖子是关于按钮单击未针对正确的模态元素。因此,如果我的帖子解决了这个问题,希望您将其标记为答案。
    猜你喜欢
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 2019-02-18
    • 2013-10-31
    • 2017-06-23
    相关资源
    最近更新 更多