【问题标题】:How to make an entire div clickable except a deep level child div?如何使除深层子 div 之外的整个 div 可点击?
【发布时间】:2019-07-23 22:58:48
【问题描述】:

我想让整个 div 可点击,但子 div 除外。这个子 div 不是 div 的直接子级,而是更深一些。我想通过传递 div id 或类名来动态排除这个子 div。

我尝试使用 jQuery “.not()” 和 “.children()” 方法来解决它,这很有效。但在某种意义上它是静态的,我需要知道 div 在哪个级别,并且需要相应地对齐方法。但是,我想要一些动态的东西,它只需要 div 的类名或 id,并从 DOM 树中找到它并将它从新的 DOM 对象链中排除,以便可以应用 jQuery“.click”和“.hover”函数在除特定 div 之外的整个 div 上。

我为我的问题创建了一个虚拟示例。在示例中,我想将除“#d3”div 之外的整个 div(即 id = main1)设为超链接。

这是我的 JSFiddle:JSFiddle

示例代码:

HTML:

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="utf-8">
            <title>
                Untitled Document
            </title>

        </meta>
    </head>
    <body>
        <div class="center border divmain1" id="main1">
            <a href="https://www.google.ca" style="display: block">
                link
            </a>
            <p>
                Main
            </p>
            <div class="border-thin divd1" id="d1">
                <p>
                    d1
                </p>
            </div>
            <div class="border-thin divd2" id="d2">
                <p>
                    d2
                </p>
                <div class="border-thin divd3" id="d3">
                    <p>
                        d3
                    </p>
                    <div class="border-thin divd4" id="d4">
                        d4
                    </div>
                    <div class="border-thin divd5" id="d5">
                        d5
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

CSS:

.border {
  border: 5px solid RosyBrown;
}
.border-thin {
  border: 2px solid RosyBrown;
}
.divmain1 {
  width: 90%;
  margin: 0 auto 0 auto;
  overflow: hidden;
}
.divd1 {
  width: 30%;
  float: left;
}
.divd2 {
  width: 60%;
  float: right;
  margin: 0 0 0 3.5%;
}
.divd3 {
  margin: auto;
  width: 90%;
}
.divd4 {
  width: 30%;
}
.divd5 {
  width: 30%;
}

jQuery:

// find elements
var main1 = $("#main1")
var d3 = $("#d3")

// handle click and hover pointer
main1.on("click", function(){
  window.open('https://www.google.ca');
});

main1.hover(function(){
  $(this).css("cursor", "pointer");
});

谁能帮助我了解如何使整个 div 可点击并动态排除子 div?

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    这里的关键是传递event 对象,这样您就可以检查实际接收click 的元素是什么。

    由于#d3 包含#d4#d5 我假设您也不希望这些元素被触发。

    如果是这种情况,您可以使用Node.contains() 来检查该元素是否是您的目标元素的后代。

    Node.contains() 方法返回一个布尔值,指示是否 节点是给定节点的后代,即节点本身,其中之一 它的直系子女,[...]

    如果您只想阻止对元素 #d3 本身的操作,则不需要 d3.contains,只需 if (e.target != d3) 即可。

    // find elements
    var main1 = $("#main1")
    var d3 = $("#d3").get(0) // Get the HTMLElement
    
    // handle click and hover pointer
    main1.on("click", function(e) {
      if (!d3.contains(e.target)) {
        console.log("I'll open a window");
      } else {
        console.log("I'm " + e.target.id + " and won't open a window")
      }
    });
    
    main1.hover(function() {
      $(this).css("cursor", "pointer");
    });
    .border {
      border: 5px solid RosyBrown;
    }
    
    .border-thin {
      border: 2px solid RosyBrown;
    }
    
    .divmain1 {
      width: 90%;
      margin: 0 auto 0 auto;
      overflow: hidden;
    }
    
    .divd1 {
      width: 30%;
      float: left;
    }
    
    .divd2 {
      width: 60%;
      float: right;
      margin: 0 0 0 3.5%;
    }
    
    .divd3 {
      margin: auto;
      width: 90%;
    }
    
    .divd4 {
      width: 30%;
    }
    
    .divd5 {
      width: 30%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="center border divmain1" id="main1">
      <a href="https://www.google.ca" style="display: block">link</a>
      <p>
        Main
      </p>
      <div class="border-thin divd1" id="d1">
        <p>d1</p>
      </div>
      <div class="border-thin divd2" id="d2">
        <p>d2</p>
        <div class="border-thin divd3" id="d3">
          <p>d3</p>
          <div class="border-thin divd4" id="d4">d4</div>
          <div class="border-thin divd5" id="d5">d5</div>
        </div>
      </div>
    </div>
    </body>
    
    </html>

    【讨论】:

    • 感谢@msg 的精彩回答;它解决了我的主要问题。你的假设是对的。由于#d4 和#d5 在#d3 中,我也想排除它们。现在我想在hover 的情况下实现同样的目标。就我而言,内部的#d4 和#d5 可能是不同的按钮,因此情况更加复杂。我现在希望光标作为#main1 div 中的“指针手”,除了#d3(但由于内部的#d4 和#d5 是按钮,我也希望它们的光标指针手)。所以,光标只会在#d3区域正常,而不是#main1,也不是#d4和#d5。
    • @Baghmama 你不能只使用css吗?在任何情况下,您都可以使用我的第二种方法来检查它是否是目标本身。
    【解决方案2】:

    在你的 jQuery 中你可以运行

    event.stopPropagation();
    

    在你不想触发初始函数的 div 子元素的点击事件中。

    【讨论】:

      【解决方案3】:

      使用cancelBubble

      例如,禁用“#d5”div 上的根事件

      $('#d5').on('click', function(e){
          // stop the event from bubbling.
          e.cancelBubble=true
      });
      

      【讨论】:

        【解决方案4】:

        我不太喜欢 jQuery,但我可以告诉你,这可以用纯 JavaScript 来完成。您所要做的就是为顶级 div 实现一个事件侦听器,并查看单击的元素或其父元素是否具有目标类。

        让我们以这个 HTML 标记为例,当有人点击 divd4 else "General Action" 中的任何内容时,我们将触发警报 "Target Locked"

        function HasSelfClassOrParent(element, classname) {
          if (element.classList && element.classList.contains(classname))
            return true;
        
          return element.parentNode && HasSelfClassOrParent(element.parentNode, classname);
        }
        
        
        let divd2 = document.querySelector(".divd2")
        let target = 'divd4'
        
        divd2.addEventListener("click", function(event) {
        
          let isTargetOrChild = HasSelfClassOrParent(event.target, target)
        
          if (isTargetOrChild) {
            alert("Target Locked")
          } else {
            alert("General Action")
          }
        
        })
        .border {
          border: 5px solid RosyBrown;
        }
        
        .border-thin {
          border: 2px solid RosyBrown;
          padding: 20px;
          margin-bottom: 10px
        }
        
        .divd4{
          background: #64B448;
          color: #fff;
          cursor: pointer;
        }
        <p>Click on div four and see what happens</p>
        
        <div class="border-thin divd2" id="d2">
          <p>I am Div 2</p>
        
          <div class="border-thin divd3" id="d3">
            <p>I am Div 3</p>
        
            <div class="border-thin divd4" id="d4">
              <p>I am a simple paragraph inside div four</p>
              <p>I am a another paragraph inside div four</p>
            </div>
        
            <div class="border-thin divd5" id="d5">
              I am Div 5
            </div>
        
          </div>
        
        </div>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-25
          • 2016-01-29
          • 1970-01-01
          • 2018-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多