Створення анкерного тегу всередині анкерного тегу


75

Під час мого випадкового тестування я побачив поведінку, коли я помістив прив'язувальний тег всередині іншого прив'язувального тегу. Я зробив jsfiddle .

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

Але в інструменті розробника це виглядає інакше:

введіть тут опис зображення

Я вважаю, що ми не можемо помістити прив'язувальний тег до іншого прив'язувального тегу, оскільки натискання на внутрішній прив'язує подію кліку до батьківського прив'язувального тегу, що не можна дозволяти.

Чи моє припущення правильне?

Відповіді:


115

Як описує @ j08691, вкладені aелементи заборонені в синтаксисі HTML. У специфікаціях HTML не сказано, чому; вони просто підкреслюють правило.

З практичної сторони браузери ефективно застосовують це обмеження у своїх правилах аналізу, тому, на відміну від багатьох інших питань, порушення специфікацій просто не буде працювати. Аналізатори ефективно розглядають <a>стартовий тег всередині відкритого aелемента як неявне закінчення відкритого елемента перед запуском нового.

Отже, якщо ви пишете <a href=foo>foo <a href=bar>bar</a> zap</a>, ви не отримаєте вкладених елементів. Браузери аналізуватимуть його як <a href=foo>foo</a> <a href=bar>bar</a> zap, тобто як два послідовних посилання, за якими йде якийсь простий текст.

З вкладеними aелементами немає нічого нелогічного : вони можуть бути реалізовані таким чином, що натискання кнопки «foo» або «zap» активує зовнішнє посилання, натискання кнопки «bar» - внутрішнє посилання. Але я не бачу підстав використовувати таку структуру, і дизайнери HTML, ймовірно, теж не бачили такої, тому вирішили заборонити її і тим самим спростити речі.

(Якщо ви дійсно хотіли імітувати вкладені посилання, ви можете використовувати звичайне посилання як зовнішнє посилання та spanелемент із відповідним обробником подій як внутрішнє “посилання”. Або ж ви можете дублювати посилання:. <a href=foo>foo</a> <a href=bar>bar</a> <a href=foo>zap</a>)


Здається, що принаймні деякі найновіші браузери дозволяють це зараз. У мене є структура, a > div > aі Chrome, і Firefox дозволяють їй існувати, як я її писав, і вони не структурують її під час аналізу (я не тестував Edge).
trusktr

Сказати, що це неможливо, насправді не корисно, вибачте.
PJ Brunet

@trusktr Я теж це тестував, і навіть така структура, як виглядає a > div > aяк <a> </a> <div> <a> </a> </div>, тому браузер дійсно не дозволяє вкладені посилання (навіть якщо є div між.
Г. Еглі

@ G.Egli Ах, ти маєш рацію. Я, мабуть, пропустив це, або я робив це за допомогою простого JavaScript. Синтаксичний аналізатор цього не дозволяє (на жаль, він не повинен перетворювати ваш HTML на те, що ви не писали, на мій погляд). Ось як цього можна досягти за допомогою JavaScript: jsfiddle.net/0ozfcn1d
trusktr

21

Вкладені посилання є незаконними.

Посилання та прив'язки, визначені елементом A, не повинні бути вкладеними; елемент A не повинен містити жодних інших елементів A.


Що може бути причиною цього? просто хочу більше роз'яснень.
Ануп,

1
Я не знаю точних міркувань за цим, проте я б сказав, що принаймні семантично не має сенсу вкладати посилання. Не кажучи вже про те, що фактичні посилання із hrefвкладеними значеннями здаються абсолютно безглуздими.
j08691

Це також моє припущення. просто хотів бути впевненішим. оскільки я можу помістити інший тег (наприклад, span) всередину тегу.
Anoop

4
Це зовсім не безглуздо. Скажімо, у вас є зовнішній якір, оформлений як великий елемент рівня блоку. Тепер десь у межах цього великого блоку, у довільному розташуванні, вам потрібен єдиний якір на рівні прольоту, який доставить вас кудись ще. Наприклад, до ярлика #comments. Це неможливо зробити без використання вкладених якорів.
DMCoding

@DanielJames - Це взагалі не має сенсу.
j08691,

10

У мене була та ж проблема, що і @thinkbonobo, і я знайшов спосіб зробити це без JavaScript:

.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>

Фокус полягає у тому, щоб зробити якір, що охоплює весь .outerdiv, а потім надати всім іншим якорям у внутрішньому div позитивне z-indexзначення. Повний кредит надходить на https://bdwm.be/html5-alternative-nested-anchor-tags/


Це працює чудово.
Pranoy C

7

Ви можете використовувати тег об’єкта для вирішення цієї проблеми. як от

<a><object><a></a></object></a>

1
Це працює напрочуд добре. Але чи це "законно" відповідно до специфікації? Характеристика така щільна і заплутана, що важко бути впевненим.
mpoisot

1
@mpoisot Це надзвичайно погана практика і хакі. Це точно не є законним або не рекомендується щодо синтаксису HTML. Прочитайте це, якщо вам потрібна додаткова інформація: w3.org/TR/html401/struct/links.html#h-12.2.2
друг

4

Я натрапив на цю проблему, намагаючись зробити панель div клікабельною також за допомогою кнопок. Обхідний шлях, який я рекомендую, - використання подій javascript.

Ось приклад codepen, який я створив .... http://codepen.io/thinkbonobo/pen/gPxJGV

Ось його HTML-частина:

Приклад посилання, вбудованого в посилання ....

<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>

Зверніть увагу, як відбувається захоплення події для внутрішнього посилання та використовується stopPropagation (). це критично важливо, щоб переконатися, що зовнішній тригер не працює.


1
Мені довелося використовувати event.preventDefault (); на Chrome
Daniel F

Проблема в тому, що mmb-click не відкриває посилання в новій вкладці.
Даніель Ф

Ви також можете зробити це без JS, див. Мою відповідь нижче

3

Це недійсний HTML.

Не можна вкладати aелементи.

Отже, за визначенням поведінка невизначена.


Що може бути причиною цього? просто хочу більше роз'яснень.
Ануп,

@Sushil - Дайте мені відповідь - що означатиме вкладений aелемент? Що це могло означати?
Отримано

Так, це не має ніякого сенсу, але для мене це було новим, тому я хотів бути впевненим, що я можу помістити теги span, img .. всередину тегу прив'язки.
Anoop

1
@Sushil - Звичайно, оскільки зміст має сенс. Наявність команди всередині команди цього не робить.
Отримано

@Anoop Я знаю, що це справді стара тема, але я все одно запропоную свою пораду. Я припускаю, чому ви не можете вкласти теги всередину інших тегів, тому що, коли ви натискаєте вкладене посилання, браузер виявляє, що два теги натиснуті одночасно (дочірній та батьківський). Це означає, що вони повинні знати якийсь пріоритет, наприклад, якому тегу важливіше слідувати. Браузери можуть також обробляти пріоритети по-іншому в порівнянні з іншими браузерами, і це просто починає зайво хитро створювати специфікацію для нього, тому краще просто уникати дозволу вкладених тегів разом.
Друг

1

Для вкладених якорів, щоб внутрішня подія не піднімалася до зовнішньої події, потрібно зупинити розповсюдження, як тільки клацне внутрішня подія.

OnClick внутрішньої події, використовуйте e.stopPropagation ();


0

Не робіть так. Я зіткнувся з такою ж проблемою у своєму додатку. Ви можете просто додати <div>тег зверху та <a>теги на рівні дитини. щось на зразок:

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

переконайтеся, що ви також додали подію кліку для myDiv у свій файл сценарію.

window.location.href = "#dashboardDetails";


0

Ви не можете вкласти теги "a". Натомість встановіть зовнішній контейнер як 'position: relative', а другий 'a' як 'position: absolute' та збільште його значення z-index. Ви отримаєте той самий ефект.

<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>

0

Я знаю, що це стара публікація, але я хочу зазначити, що відповідь user9147812 спрацювала краще за будь-яку іншу пропозицію. Ось як я склав цілу справу.

    <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>

-6

Це поганий спосіб кодування, але ви можете спробувати це -

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


6
Подібно до того, як це було схоже на злом браузера з 1996 року, це не спрацювало б. Принаймні у Firefox він намагається зрозуміти це, закриваючи зовнішній якір, коли знаходить початок внутрішнього якоря. Це також передбачало б закриття елементів td, td та таблиці, а потім повторне їх відкриття знову після закриття внутрішнього якоря. Я бачив цю точну поведінку в шаблоні WooCommerce, висвітлюючи деякі досить прикольні та неочевидні проблеми форматування, що призвело мене до цього SO-питання, намагаючись знайти відповідь.
Джейсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.