web-dev-qa-db-de.com

Dropdown-Menü beim Hover anzeigen und bei Klick nur mit CSS schließen

Kann mir jemand mit einer Erklärung helfen, warum die Links aus einem Dropdown-Menü nicht funktionieren, wenn ich darauf klicke? Vielleicht wegen Zeigerereignissen? Ich versuche, ein Dropdown-Menü zu haben, das geschlossen wird, nachdem auf einen Link oder auf die Schaltfläche zum Schließen geklickt wurde. Ich habe ein paar coole Sachen hinzugefügt, wie das Ausblenden eines übergeordneten Containers, wenn auf einen Link geklickt wird.

Dafür gibt es viele Möglichkeiten:

  1. mit :focus, aber wenn der Fokus verwendet wird, wird das Dropdown nicht beim nächsten Hover über Dropdown .__ ausgelöst.

  2. verwenden Sie :active für Container und pointer-events, um nur auf die aktiven -Links zu zeigen, Zeigerereignisse sind jedoch fehlerhaft

  3. :target verwendet, hat jedoch das gleiche Problem wie: focus, löst nicht den zweiten Staubsauger aus

body {
    padding: 20px;
}
.container {
    border: 1px solid Lime;
    padding: 10px;
    width: 200px;
}
.test1 {
    display: none;
    border: 1px dashed orange;
    background: green;
    padding: 10px;
    pointer-events: none;
}
.container:hover .test1 {
    display: inline-block;
}
.container:hover .test1:active {
    display: none;
}
a {
    pointer-events: auto;
    color: Lime;
    font-weight: bold;
}
<ul class="container">
	 Drop down menu
	<li class="test1">
	<a class="dropdown" href="#">X Close</a>
	<ul class="content">
		 CLOSE THIS CONTENT
		<li class="link"><a href="http://www.google.com">Go to link 1</a></li>
		<li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
		<li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
	</ul>

12
RulerNature

Quick Check: Working JSFiddle

Kann mir jemand mit einer Erklärung helfen, warum die Links aus einem Dropdown-Menü nicht funktionieren, wenn ich auf sie klicke? Vielleicht wegen Zeigerereignissen?

Erklärung, warum dieses Verhalten so ist : Ja, Sie haben Recht. Es liegt an der Art und Weise, wie Sie die Selektorlogik :active Verwenden Beachten Sie im Detail diese CSS-Regel

.container:hover .test1:active {
    display: none;
}

Sie haben Ihre Menü-Links unter Ihrem Haupt-li.test1 Und jeder Klick auf die inneren Links sprudelt auch bis zu diesem Element, also ist es so gut wie das Klicken auf li. Sobald Sie die Maustaste gedrückt halten (mouse down event), wird das Ereignis :active Ausgelöst und Sie verstecken das links (dh: li.test1), Aber ein Das Klickereignis ist nur abgeschlossen, wenn die Maus sowohl gedrückt als auch gedrückt ist . Inzwischen ist die li ausgeblendet und die mouse up Ist nicht mehr im Link. Wie Sie sehen, besteht keine Chance, dass das Klickereignis ausgelöst wird. Das ist das Problem.


I saw other answers which you seem to be interested in and this really doesn't need any kind of hack, It can be done by just formatting your HTML and with some CSS changes.


Lösung: Anstatt Ihre inneren Menü-Links in den li.test1 Einzuschließen, können Sie mit zwei arbeiten verschiedene li, eine für den X CLose und eine andere für das Halten des menu links. Mit dieser Option können wir sicherstellen, dass , wann immer der li.test1 Aktiv ist (dh die Maus ist gedrückt), wir können verstecke es und auch die anderen neuen li, die daneben liegen. Das heißt also, wann immer der Benutzer auf X Closeli klickt, wird das Menü ausgeblendet. Wenn er auf die anderen Menüpunkte klickt, werden Sie umgeleitet.

Die Änderungen in Ihrer HTML-Struktur sollten also so aussehen

<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
  </li>
  <li class="MenuLinks">
    <ul class="content">
      <!-- all your links go here-->
    </ul>
  </li>
</ul>

Und Haupt-CSS-Regel ist

.container:hover .test1:active,
.container:hover .test1:active + .MenuLinks {
  display: none;
}

Unten ist ein SO funktionierendes Snippet

body {
  padding: 20px;
}
.container {
  border: 1px solid Lime;
  padding: 10px;
  width: 200px;
  list-style-type: none;
}
.test1,
.MenuLinks {  
  display: none;
  border-color: orange;
  border-style: dashed;
  background: green;
  pointer-events: none;
}
.test1 {
  padding: 10px;
  border-width: 1px 1px 0px 1px;
}
.MenuLinks {
  border-width: 0px 1px 1px 1px;
}
.container:hover li {
  display: block;
}

/*Rule to hide both test1 and MenuLinks when X Close is clicked*/
.container:hover .test1:active,
.container:hover .test1:active + .MenuLinks {
  display: none;
}


a {
  pointer-events: auto;
  color: Lime;
  font-weight: bold;
}
<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
  </li>
  <!--seperate li for close-->

  <li class="MenuLinks">
    <!--wrap all your menu items here-->
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
      </li>
    </ul>
    <li>
</ul>

Hinweis: Der leere Bildschirm, wenn Sie auf die Links klicken, ist auf die Sicherheitseinschränkungen von Google für Cross Origin zurückzuführen, die diesen Fehler in der Konsole verursachen

Refused to display 'https://www.google.co.in/?gfe_rd=cr&ei=x2VWWLL2Ae-K8Qfwx4ngDQ' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.

Sie können die Anforderungen jedoch auf der Registerkarte Netzwerk sehen, wenn Sie auf die Links klicken.

Hoffe das hilft!!

3
Rajshekar Reddy

Ich würde dies normalerweise mit JS machen - aber mit CSS gibt es is einen Hack:

Erstellen Sie zuerst eine Eingabe mit der ID close und einer label, die unsere Schließen-Schaltfläche einschließt:

  <input type="radio" id="close" />
  <li class="test1">
    <label for="close">
      <a class="dropdown" href="#">X Close</a>
    </label>

und fügen Sie in diesem Stil anstelle des aktuellen .test1:active hinzu:

.container:hover #close:active + .test1{
  display: none;
}
#close {
  display: none;
}

Siehe Demo unten:

body {
  padding: 20px;
}
.container {
  border: 1px solid Lime;
  padding: 10px;
  width: 200px;
}
.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}
.container:hover .test1 {
  display: inline-block;
}
#close {
  display: none;
}
.container:hover #close:active + .test1 {
  display: none;
}
a {
  pointer-events: auto;
  color: Lime;
  font-weight: bold;
}
<ul class="container">
  Drop down menu
  <input type="radio" id="close" />
  <li class="test1">
    <label for="close">
      <a class="dropdown" href="#">X Close</a>
    </label>
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
      </li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
      </li>
    </ul>
  </li>
</ul>

Der obige Code enthält jedoch ein ungültiges input-Element in einer ul - um zu verhindern, dass Sie das Markup ein wenig bearbeiten können, um einen weiteren Wrapper für die ul zu erstellen (möglicherweise müssen Sie die Breiten/Auffüllung aufgrund der Markup-Änderung ein wenig anpassen) Code siehe unten:

body {
  padding: 20px;
}
.container {
  border: 1px solid Lime;
  padding: 10px;
}
ul {
  width: 200px;
}
.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}
.container:hover .test1 {
  display: inline-block;
}
#close {
  display: none;
}
.container:hover #close:active + ul > li.test1 {
  display: none;
}
a {
  pointer-events: auto;
  color: Lime;
  font-weight: bold;
}
<div class="container">
  Drop down menu
  <input type="radio" id="close" />
  <ul>
    <li class="test1">
      <label for="close">
        <a class="dropdown" href="#">X Close</a>
      </label>
      <ul class="content">
        CLOSE THIS CONTENT
        <li class="link"><a href="http://www.google.com">Go to link 1</a>
        </li>
        <li class="link"><a href="https://www.google.co.uk">Go to link 2</a>
        </li>
        <li class="link"><a href="https://www.google.co.uk">Go to link 3</a>
        </li>
      </ul>
    </li>
  </ul>
</div>

4
kukkuz

Sie können label und button in a verwenden, um den Link zu schließen. 

body {
  padding: 20px;
}

.container {
  border: 1px solid Lime;
  padding: 10px;
  width: 200px;
}

.test1 {
  display: none;
  border: 1px dashed orange;
  background: green;
  padding: 10px;
  pointer-events: none;
}

.container:hover .test1 {
  display: inline-block;
}

a, label {
  pointer-events: auto;
  color: Lime;
  font-weight: bold;
}

/* close button */
#xclose:active + .test1 {
  display:none;
}

#xclose {
  display: none;
}
<ul class="container">
  Drop down menu
  <button id="xclose">X close</button>
  <li class="test1">    
    <label class="dropdown" for="xclose">X Close</label>        
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </li>
</ul>

Hoffe, das wird dir irgendwie helfen (y).

1

Ich würde vorschlagen entfernen

.container:hover .test1:active {
    display: none;
}

wenn Sie auf den Link "X Close" klicken, können Sie einen anderen Weg finden (ein paar Zeilen Javascript). (Einige HTML-Tags wurden übrigens auch behoben). Nun funktionieren die Links:

body {
    padding: 20px;
}
.container {
    border: 1px solid Lime;
    padding: 10px;
    width: 200px;
}
.test1 {
    display: none;
    border: 1px dashed orange;
    background: green;
    padding: 10px;
    pointer-events: none;
}
.container:hover .test1 {
    display: inline-block;
}
a {
    pointer-events: auto;
    color: Lime;
    font-weight: bold;
}
<ul class="container">
  Drop down menu
  <li class="test1">
    <a class="dropdown" href="#">X Close</a>
    <ul class="content">
      CLOSE THIS CONTENT
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </li>
</ul>

1
Theodore K.

Es scheint nicht zu funktionieren, da beim Herunterklappen der :hover- Klasse das Dropdown-Menü geöffnet bleibt. Das Mouse-up-Ereignis wird daher nicht für die Verknüpfung ausgeführt, da das Dropdown-Menü bereits wieder geschlossen ist und kein Klick erfolgt. Sie sollten Javascript verwenden, um das Dropdown-Menü zu öffnen und zu schließen.

1
Martin Cup

In CSS können Sie label-Elemente an inputs binden. Aus diesem Grund können Sie die Schließen-Schaltfläche an einen Eingang binden, der - falls aktiv - die Liste wieder verbirgt.

body{
  padding: 20px;
}

a, label{
  text-decoration: none;
  cursor: pointer;
  color: Lime;
  font-weight: bold;
}

.container{
  border: 1px solid Lime;
  padding: 10px;
  width: 200px;
}

.dropdown{
  display: none;
  border: 1px solid orange;
  background: green;
  margin-top: 10px;
  padding: 10px;
}

#close, #close:active + .dropdown{
  display: none;
}

.container:hover .dropdown{
  display: block;
}

.dropdown > ul{
  padding: 0;
  list-style: none;
}
<div class="container">
  Drop down menu
  <button id="close"></button>
  <div class="dropdown">
    <label for="close">X Close</label>
    <ul>
      <li class="link"><a href="http://www.google.com">Go to link 1</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
      <li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    </ul>
  </div>
</div>

Die input mit id="close" wird vor der Liste eingefügt und wird vom Label mit for="close" ausgelöst.
Wenn es ausgelöst wird, wird die folgende Regel wirksam:

#close, #close:active + .dropdown{
  display: none;
}

Was verbirgt die Liste.
Wenn Sie jedoch über den .container fahren, wird er erneut angezeigt, sodass Sie den Vorgang wiederholen können. Eine Eingabe reicht aus.

Es gab auch ein paar Fehler in Ihrem Code. Sie hatten den Text Drop down menu und CLOSE THIS CONTENT direkt in einer ul, was nicht möglich ist. Eine ul kann nur lis enthalten und sonst nichts.

Hoffe das hilft

0
Gust van de Wal

Ich würde vorschlagen, jQuery zu verwenden, um den Container nur dann zu schließen, wenn ein Link gedrückt wird. pointer-events hat viele Probleme. Aus diesem Grund haben sie beschlossen, die Funktion auf CSS4 zu verschieben.

Ich denke auch, dass pointer-events: none; verhindert, dass Klickereignisse ausgelöst werden. Daher funktioniert die Verwendung von jQuery nur für den Link nicht. Ich denke, Sie müssen das Öffnen und Schließen des Containers mit jQuery korrigieren.

0
Kevinvhengst

Eine der Optionen ist die Verwendung von animate. Ich habe mit opacity ein Beispiel für Ihren Code angegeben. Die Verwendung von visibility:hidden oder overflow:hidden verbessert Ihren Code.

    body {
        padding: 20px;
    }
    .container {
        border: 1px solid Lime;
        padding: 10px;
        width: 200px;
    }
    .test1 {
        display: none;
        border: 1px dashed orange;
        background: green;
        padding: 10px;
        pointer-events: none;
    }
    .container:hover .test1 {
        display: inline-block;
    }
    
    a {
        pointer-events: auto;
        color: Lime;
        font-weight: bold;
    }


.container .test1 {
  -webkit-animation: seconds 1.0s forwards;
  -webkit-animation-iteration-count: 1;
  -webkit-animation-delay: 2s;
  animation: seconds 1.0s forwards;
  animation-iteration-count: 1;
  animation-delay: 2s;
  position: relative;
}
@-webkit-keyframes seconds {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;

  }

@keyframes seconds {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0;

  }
}
    <ul class="container">
    	 Drop down menu
    	<li class="test1">
    	<a class="dropdown" href="#">X Close</a>
    	<ul class="content">
    		 CLOSE THIS CONTENT
    		<li class="link"><a href="http://www.google.com">Go to link 1</a></li>
    		<li class="link"><a href="https://www.google.co.uk">Go to link 2</a></li>
    		<li class="link"><a href="https://www.google.co.uk">Go to link 3</a></li>
    	</ul>
0
shubham agrawal
.container:hover .test1:active {
display: none;
}

Ändere das gerne zu

.container:hover .test1:focus{
    display: none;
    }

Was hier passiert, ist, dass, wenn Ihr Div den "aktiven" Pseudo-Code von Ihrem Link-Klick erhält, dieser sich vor dem DOM verbirgt, um die Weiterleitung zu erhalten. Wenn Sie den Fokus ändern, kann der Klick tatsächlich durchlaufen werden.

0
jjeining

Warum haben Sie "pointer-events: none;" zum Listenelement .test1 hinzugefügt? Dadurch wird Ihr pointer-events: auto; überschrieben. Versuchen Sie, ihn zu entfernen, da er Ihr Klickereignis bindet.

0
ReAlPeNx