Ankertag innerhalb des Ankertags erstellen

75

Während meiner zufälligen Tests habe ich ein Verhalten festgestellt, bei dem ich ein Ankertag in ein anderes Ankertag eingefügt habe. Ich habe eine Geige gemacht .

<a class="groupPopper">
     <a class="name"> content</a>
</a>​

Im Entwicklertool sieht es jedoch anders aus:

Geben Sie hier die Bildbeschreibung ein

Ich glaube, wir können kein Ankertag in ein anderes Ankertag einfügen, da durch Klicken auf den inneren Anker das Klickereignis zum übergeordneten Ankertag hochsprudelt, was nicht zulässig sein sollte.

Ist meine Annahme richtig?

Anoop
quelle

Antworten:

114

Wie @ j08691 beschreibt, sind verschachtelte aElemente in der HTML-Syntax verboten. HTML-Spezifikationen sagen nicht warum; Sie betonen nur die Regel.

Auf der praktischen Seite setzen Browser diese Einschränkung in ihren Parsing-Regeln effektiv durch. Im Gegensatz zu vielen anderen Problemen funktioniert ein Verstoß gegen die Spezifikationen einfach nicht. Die Parser behandeln ein <a>Start-Tag in einem offenen aElement effektiv als implizites Beenden des offenen Elements, bevor ein neues gestartet wird .

Wenn Sie also schreiben <a href=foo>foo <a href=bar>bar</a> zap</a>, erhalten Sie keine verschachtelten Elemente. Browser analysieren es als <a href=foo>foo</a> <a href=bar>bar</a> zap, dh als zwei aufeinanderfolgende Links, gefolgt von einfachem Text.

Verschachtelte aElemente sind von Natur aus nicht unlogisch : Sie können so implementiert werden, dass durch Klicken auf "foo" oder "zap" der äußere Link und durch Klicken auf "bar" der innere Link aktiviert wird. Aber ich sehe keinen Grund, eine solche Struktur zu verwenden, und die HTML-Designer haben wahrscheinlich auch keine gesehen, also haben sie beschlossen, sie zu verbieten und dadurch die Dinge zu vereinfachen.

(Wenn Sie wirklich verschachtelte Links simulieren möchten, können Sie einen normalen Link als äußeren Link und ein spanElement mit einem geeigneten Ereignishandler als inneren „Link“ verwenden. Alternativ können Sie Links duplizieren : <a href=foo>foo</a> <a href=bar>bar</a> <a href=foo>zap</a>.)

Jukka K. Korpela
quelle
Scheint, als ob zumindest einige der neuesten Browser dies jetzt zulassen. Ich habe eine Struktur a > div > aund Chrome und Firefox lassen sie beide so existieren, wie ich sie geschrieben habe, und sie lösen sie während des Parsens nicht auf (ich habe Edge nicht getestet).
Trusktr
Zu sagen, dass es nicht möglich ist, ist nicht wirklich hilfreich, sorry.
PJ Brunet
@trusktr Ich habe es auch getestet und sogar eine Struktur wie a > div > a<a> </a> <div> <a> </a> </ div> erscheint, sodass der Browser wirklich keine verschachtelten Links zulässt (selbst wenn vorhanden) ist ein div ist zwischen.
G. Egli
@ G.Egli Ah, du hast recht. Ich muss es übersehen haben, oder ich habe es mit einfachem JavaScript gemacht. Der Parser erlaubt es nicht (was für eine Schande, er sollte Ihren HTML-Code meiner Meinung nach nicht in etwas verwandeln, das Sie nicht geschrieben haben). So kann es mit JavaScript erreicht werden: jsfiddle.net/0ozfcn1d
trusktr
21

Verschachtelte Links sind illegal.

Vom A-Element definierte Links und Anker dürfen nicht verschachtelt sein. Ein A-Element darf keine anderen A-Elemente enthalten.

j08691
quelle
Was kann der Grund dafür sein? Ich möchte nur mehr Klarheit.
Anoop
1
Ich kenne die genauen Gründe dafür nicht, aber ich würde zumindest semantisch sagen, dass es keinen Sinn macht, Links zu verschachteln. hrefGanz zu schweigen davon, dass tatsächliche Verknüpfungen mit verschachtelten Werten völlig sinnlos sind.
j08691
Das ist auch meine Annahme. wollte nur sicherer sein. da ich ein anderes Tag (z. B. span) in ein Tag einfügen kann.
Anoop
3
Es ist überhaupt nicht sinnlos. Angenommen, Sie haben einen Außenanker, der als großes Element auf Blockebene gestaltet ist. Irgendwo innerhalb dieses großen Blocks, an einer beliebigen Stelle, möchten Sie einen einzelnen Anker auf Span-Ebene, der Sie an einen anderen Ort bringt. Zum Beispiel zu einer Verknüpfung #comments. Ohne verschachtelte Anker ist dies nicht möglich.
DMCoding
@ DanielJames - Das macht überhaupt keinen Sinn.
j08691
9

Ich hatte das gleiche Problem wie @thinkbonobo und habe einen Weg gefunden, dies ohne JavaScript zu tun:

.outer {
  position: relative;
  background-color: red;
}
 
.outer > a {
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}
 
.inner {
  position: relative;
  pointer-events: none;
  z-index: 1;
}
 
.inner a {
  pointer-events: all;
}
<div class="outer">
  <a href="#overlay-link"></a>
  <div class="inner">
    You can click on the text of this red box. It also contains a
    <a href="#inner-link">W3C compliant hyperlink.</a>
  </div>
</div>

Der Trick besteht darin, einen Anker zu erstellen, der das gesamte .outerDiv bedeckt , und dann allen anderen Ankern im inneren Div einen positiven z-indexWert zu geben. Das volle Guthaben geht an https://bdwm.be/html5-alternative-nested-anchor-tags/


quelle
7

Sie können das Objekt-Tag verwenden, um dieses Problem zu lösen. sowie

<a><object><a></a></object></a>
user9147812
quelle
1
Das funktioniert überraschend gut. Aber ist es laut Spezifikation "legal"? Die Spezifikation ist so dicht und verworren, dass es schwer ist, sicher zu sein.
mpoisot
1
@mpoisot Das ist extrem schlechte Praxis und hacky. Es ist definitiv nicht legal oder in Bezug auf die HTML-Syntax empfohlen. Lesen Sie dies, wenn Sie weitere Informationen benötigen: w3.org/TR/html401/struct/links.html#h-12.2.2
Ein Freund
4

Ich bin auf dieses Problem gestoßen, als ich versucht habe, ein Div-Panel anklickbar zu machen, indem ich auch Schaltflächen habe. Die von mir empfohlene Problemumgehung besteht darin, Javascript-Ereignisse zu verwenden.

Hier ist ein Codepen-Beispiel, das ich erstellt habe ... http://codepen.io/thinkbonobo/pen/gPxJGV

Hier ist der HTML-Teil davon:

Beispiel eines in den Link eingebetteten Links ....

<div class=panel onclick="alert('We\'ll hi-ii-ii-ide')">
  If you say run<br>
  <button onclick="app.hitMe(event)">more</button><br>
  <br>
  And if you say hide...<br>
</div>

Beachten Sie, wie das Ereignis für den inneren Link erfasst und stopPropagation () verwendet wird. Dies ist wichtig, um sicherzustellen, dass der äußere Auslöser nicht ausgeführt wird.

ThinkBonobo
quelle
1
Ich musste event.preventDefault () verwenden; auf Chrome
Daniel F
Es hat das Problem, dass mmb-click den Link in einer neuen Registerkarte nicht öffnet.
Daniel F
Sie können dies auch ohne JS tun, siehe meine Antwort unten
3

Es ist ungültiges HTML.

Sie können keine aElemente verschachteln .

Per Definition ist das Verhalten also undefiniert.

Oded
quelle
Was kann der Grund dafür sein? Ich möchte nur mehr Klarheit.
Anoop
@Sushil - Antworte mir - was würde ein verschachteltes aElement bedeuten ? Was könnte es möglicherweise bedeuten?
Oded
Ja, es macht keinen Sinn, aber es war neu für mich, also wollte ich sicher sein, dass ich span, img .. Tags in Anker-Tags einfügen kann.
Anoop
1
@Sushil - Sicher, als Inhalt macht es Sinn. Einen Befehl in einem Befehl zu haben, tut dies nicht.
Oded
@ Anoop Ich weiß, dass dies ein wirklich alter Thread ist, aber ich werde trotzdem meinen Rat geben. Ich vermute, warum Sie keine Tags in anderen Tags verschachteln können, weil der Browser beim Klicken auf den verschachtelten Link erkennt, dass zwei Tags gleichzeitig angeklickt wurden (das Kind und das Elternteil). Dies bedeutet, dass sie eine Priorität kennen müssen, wie z. B. ein Tag wichtiger ist, dem sie folgen müssen. Browser behandeln Prioritäten möglicherweise auch anders als andere Browser, und es wird unnötig schwierig, eine Spezifikation dafür zu erstellen. Vermeiden Sie daher am besten, verschachtelte Tags insgesamt zuzulassen.
Ein Freund
1

Bei verschachtelten Ankern möchten Sie die Ausbreitung stoppen, sobald das innere Ereignis angeklickt wird, um zu verhindern, dass das innere Ereignis zum äußeren Ereignis aufsteigt.

Verwenden Sie beim Klicken auf das innere Ereignis e.stopPropagation ().

Adi Sekar
quelle
0

Mach es nicht so. Ich hatte das gleiche Problem in meiner App. Sie können einfach ein <div>Tag oben und <a>Tags auf untergeordneter Ebene hinzufügen . etwas wie:

<div id="myDiv"><a href="#"></a>
     <a href="#"></a>
</div>

Stellen Sie sicher, dass Sie in Ihrer Skriptdatei auch ein Klickereignis für myDiv hinzufügen.

window.location.href = "#dashboardDetails";

Rahul Varma
quelle
0

Sie können keine 'a'-Tags verschachteln. Setzen Sie stattdessen den äußeren Container als 'Position: relativ' und das zweite 'a' als 'Position: absolut' und erhöhen Sie seinen Z-Index-Wert. Sie erhalten den gleichen Effekt.

<div style="position:relative">
<a href="page2.php"><img src="image-1.png"></a>
<a style="position:absolute;top:0;z-index:99" href="page1.php"></a>
</div>
Vidhya
quelle
0

Ich weiß, dass es ein alter Beitrag ist, aber ich möchte darauf hinweisen, dass die Antwort von user9147812 besser funktioniert hat als alle anderen Vorschläge. So habe ich das Ganze gestapelt.

    <style>
    * {
      padding: 0;
      margin: 0 border:0;
      outline: 0;
    }

    .outer_anchor {
      display: inline-block;
      padding: 5px 8px;
      margin: 2px;
      border: 1px solid #252632;
      border-radius: 3px;
      background: #1c1d26;
      color: #fff;
      text-shadow: 0 1px 0 #616161;
      box-shadow: 1px 1px 3px #000;
      transform: translateY(0);
      transition: background 250ms;
    }
    .inner_anchor {
      display: inline-block;
      padding: 5px 8px;
      margin: 2px;
      border: 1px solid #252632;
      border-radius: 3px;
      background: #1c1d26;
      color: #fff;
      transform: translate(0px);
    }
    .inner_anchor:hover {
      background: #647915;
    }
    </style>


<a href="#">ItemX<object><a class="elim_btn" href="#" title='Eliminate'>&times;</a></object></a>
Alter Sam
quelle
-6

Dies ist eine schlechte Art der Codierung, aber Sie können dies versuchen -

<a href="1"> aaaa <table> <tr> <td> <a href="2"> bbbb </a> </ td> </ tr> </ table> </a>

Pragyandipta Tripathy
quelle
6
Dies würde nicht nur wie ein Browser-Hack von 1996 aussehen, sondern auch nicht funktionieren. Zumindest in Firefox würde es versuchen, dies zu verstehen, indem der äußere Anker geschlossen wird, wenn er den Anfang des inneren Ankers findet. Dazu müssten auch die Elemente td, td und table geschlossen und dann alle erneut geöffnet werden, nachdem der innere Anker geschlossen wurde. Ich habe genau dieses Verhalten in einer WooCommerce-Vorlage gesehen, die einige ziemlich funky und nicht offensichtliche Formatierungsprobleme aufwirft, die mich zu dieser SO-Frage geführt haben, bei der versucht wurde, eine Antwort zu finden.
Jason