Wie erstelle ich mit l () einen leeren Nur-Anker-Link?

20

Ich versuche l(), so etwas <a href='#' ...>für Ajax-Calling-Zwecke zu verwenden. /programming/1698453/drupal-creating-anchor-only-link-with-l ist sehr nah an die Richtige - eine Option verwenden , in l()wie 'fragment' => 'foo'einen Link wie zu produzieren <a href='#foo'...>- aber ich bin versuche ein sauberes '#' zu bekommen. Gibt es eine Möglichkeit, dies zu tun, oder sollte ich einfach etwas als Teil des Fragments einfügen und mir darüber keine Sorgen machen?

Jim Miller
quelle

Antworten:

12

Wenn Sie kein sauberes "#" mit Fragment verwenden könnten, würde ich Ihnen die Verwendung empfehlen <a href="javascript:">link</a>.
Wenn Sie dem hrefAttribut "javascript:" oder "javascript: void (0)" hinzufügen , wird das <a>Tag nichts tun. Dann können Sie "onclick" für Ihren Ajax-Zweck an den Link binden.
Sie können dies mit der folgenden l()Funktion implementieren :

     l('link', 'javascript:',  array('external' => TRUE));
Sithu
quelle
Was ist mitjavascript:void(0)
Serjas
1
@Serjas, javascript:und javascript:void(0)sind gleich. Der einzige Unterschied ist "void (0)" :)
Sithu
Ich meine, werde ich () konvertieren ()?
Serjas
6
Sie sollten niemals solche Spielereien verwenden und nur ereignisgesteuertes JavaScript verwenden! Dies ist 2012 und nicht 2004. Warum wurde eine Antwort von so geringer Qualität gewählt? Beliebt, weil es einfach ist? Aber es ist extrem falsch. :(
@chx, da Sie ein Drupal-Core-Betreuer sind, hoffe ich, dass Sie nicht missbrauchen, den zweiten Parameter nicht für die Funktion l (), sondern für Pfad oder Fragment zu verwenden. Leider akzeptiert die Funktion "Javascript" als Pfad :) Wenn es extrem falsch ist, warum akzeptiert Drupal es? Wahrscheinlich wird es in den späteren Drupal-Versionen eingeschränkt sein.
Sithu
15

Zeit für ein PHP-Typografie-Pop-Quiz! (Vollständige Offenlegung: Ich habe in unserem Büro nicht gewonnen).

Wie bereits erwähnt, ist dies der Code l(), mit dem wir uns befassen:

if (isset($options['fragment']) && $options['fragment'] !== '') {
  $options['fragment'] = '#' . $options['fragment'];
}

Hier ist die Frage: Welcher Wert wird in eine leere Zeichenfolge umgewandelt, übergibt jedoch Folgendes?

(isset($var) && $var !== '')

Die Antwort lautet FALSE:!

Also könnten wir das versuchen:

l(t('My link'), NULL, array('fragment' => FALSE));

Welches gibt uns:

<a href="/#">My link</a>

Zum Glück können wir diesen führenden Schrägstrich entfernen, indem wir ihn weitergeben external => TRUE:

l(t('My link'), NULL, array('external' => TRUE, 'fragment' => FALSE));

Welches gibt uns:

<a href="#">My link</a>

Boom. Was tun wir, um das manuelle Verketten von HTML-Strings zu vermeiden?

Nachsatz:

Ich bin mir nicht sicher, ob ich unter normalen Umständen empfehlen würde, einen solchen Link von PHP aus zu drucken. Ohne Ihr Javascript wird der gesamte Link dazu führen, dass Ihr Benutzer an den Anfang der Seite springt ( was zu meiner kleinen Überraschung ein spezielles Verhalten ist ). Es sollte wahrscheinlich irgendwo hinweisen, dass ohne Javascript funktioniert.

Wenn der Link wirklich nur mit Javascript Sinn macht (wie die Steuerelemente für eine Diashow nur mit js oder so), halte ich es für besser, den Link zur Seite mit Javascript hinzuzufügen. Wenn Sie es aber auch wirklich in Ihre Quelle einfügen möchten, vergewissern Sie sich, dass dies display:nonestandardmäßig der Fall ist . Drupal hat die .jsKlasse auf dem HTML, um sie dann anzuzeigen, wenn Javascript vorhanden ist.

Stephen Tweeddale
quelle
7

Leider macht die url()Funktion (die l()intern aufruft) mit den folgenden Zeilen so ziemlich jede Chance auf ein leeres Fragment zunichte:

if (isset($options['fragment']) && $options['fragment'] !== '') {
  $options['fragment'] = '#' . $options['fragment'];
}

Es wird überprüft, ob das Fragment keine leere Zeichenfolge ist. Dies ist die Zeichenfolge, die Sie übergeben müssen, um das Fragment zu bereinigen #. Ich denke, die einfachste Lösung wäre, die ID eines geeigneten Elements irgendwo auf der Seite auszuwählen und diese stattdessen für das Fragment zu verwenden (oder javascript:voidwie Sithu es erwähnt hat).

Der am besten zugängliche Weg (und später in vielen Ländern auf legalem Wege; denken Sie an Abschnitt 508 in den Staaten, die DDA in Großbritannien usw.) wäre jedoch, den Inhalt bereitzustellen, der von Ihrem Link auf geladen / angepasst wird eine separate Seite und verwenden Sie stattdessen die URL für diese Seite als href des Links. Sie würden dann JavaScript verwenden, um zu verhindern, dass das Ereignis auf dem Link die Seite für die Browser, in denen es aktiviert ist, tatsächlich umleitet.

Auf diese Weise haben Sie Fallback-Inhalte für Benutzer ohne Javascript, bleiben legal und halten alle und ihren Hund bei Laune :)

Clive
quelle
Großartige Bearbeitung über Fallback! Wenn wir die ajax-URL in der href des Links verwenden, kann die aufrufende Seite ein darstellbares HTML sein, wenn Javascript deaktiviert ist? Ich hatte schon einmal print drupal_json_output($output)in meinem Ajax anrufende Seite.
Sithu
4

Sauber konnte man nicht gebrauchen #.

Aber es ist möglich hinzuzufügen space symbolnach #:

  l('Link title', '# ', array('external' => TRUE));
milkovsky
quelle
2

Ich hatte nur das gleiche Problem, aber keine der Lösungen war zufriedenstellend, und so kam ich auf meine eigene:

l('link', '', array('fragment' => ' ', 'html' => TRUE, 'external' => TRUE));

Dies erzeugt eine saubere #

<a href="#">link</a>
David Sidler
quelle
Nah, das ergibt sich <a href="# ">link</a>für mich.
tyler.frankenstein
1

Ich würde stattdessen den Render-Typ html_tag verwenden, da ich glaube, dass der Render- Link von Drupal besondere Aufmerksamkeit erhält. Der Nachteil ist, dass es keine Abkürzungsfunktion dafür gibt. Daher müssen wir ein Render-Array verwenden:

array (
  '#type' => 'html_tag',
  '#tag' => 'a',
  '#attributes' => array (
    'href' => '#',
  ),
);
Jigarius
quelle
0

Dies ist im Grunde die gleiche Antwort, die ich hier gepostet habe ... Die Einstellung fragmentauf ein einzelnes Leerzeichen wird in ein umgewandelt #und $current_pathist enthalten, da ansonsten der Link nur auf gesetzt wird, www.example.com/#anstatt auf www.example.com/current-page#:

$current_path = check_url(drupal_get_path_alias($_GET['q']));
$link = l('link', $current_path, array('fragment' => ' '));
Scherzhaftigkeit
quelle
Es ist nicht erforderlich, den Pfadalias abzurufen, da l () für Sie in einen Alias ​​konvertiert. Es ist eigentlich vorzuziehen, einen nicht mit Alias ​​versehenen Pfad zu verwenden.
Rooby