¿Cómo crear un enlace de anclaje VACÍO con l ()?

20

Estoy tratando de usar l()para obtener algo como <a href='#' ...>, para fines de llamadas ajax. /programming/1698453/drupal-creating-anchor-only-link-with-l está muy cerca de lo correcto: use una opción en me l()gusta 'fragment' => 'foo'para producir un enlace como <a href='#foo'...>, pero estoy tratando de obtener un '#' limpio. ¿Hay alguna forma de hacer esto, o debería simplemente poner algo como parte del fragmento y no preocuparme?

Jim Miller
fuente

Respuestas:

12

Si no pudieras usar "#" limpio con fragmento, te sugiero que lo uses <a href="javascript:">link</a>.
Al agregar "javascript:" o "javascript: void (0)" al hrefatributo, la <a>etiqueta no hará nada. Luego puede vincular "onclick" al enlace para su propósito ajax.
Puede implementar esto usando la l()función de la siguiente manera:

     l('link', 'javascript:',  array('external' => TRUE));
Sithu
fuente
que pasajavascript:void(0)
Serjas
1
@Serjas, javascript:y javascript:void(0)son lo mismo. La única diferencia es "void (0)" :)
Sithu
Quiero decir ¿l () convert ()?
Serjas
66
¡Nunca debe usar tales travesuras y solo usar JavaScript impulsado por eventos! Esto es 2012 no 2004. ¿Por qué se vota una respuesta de tan baja calidad? ¿Popular porque es fácil? Pero está extremadamente mal. :(
@chx, como eres un mantenedor de drupal core, espero que no estés abusando de no usar el segundo parámetro para la función l () en lugar de path o fragment. Desafortunadamente, la función acepta "javascript" como ruta :) Si está extremadamente mal, ¿por qué Drupal lo acepta? Probablemente, estará restringido en las versiones posteriores de Drupal.
Sithu
15

¡Tiempo de prueba pop de tipografía PHP! (Divulgación completa: no gané en nuestra oficina).

Como ya se señaló, este es el código l()que nos preocupa:

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

Así que aquí está la pregunta: ¿Qué valor se convierte en una cadena vacía pero pasa lo siguiente?

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

La respuesta es FALSE:!

Entonces, podríamos intentar esto:

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

Lo que nos da:

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

Afortunadamente, podemos eliminar esa barra diagonal al pasar external => TRUE:

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

Lo que nos da:

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

Auge. Lo que hacemos para evitar concatenar cadenas html manualmente, ¿eh?

Posdata:

No estoy seguro de que recomendaría imprimir un enlace como este desde PHP en circunstancias normales. Sin su javascript, todo ese enlace lo hará saltar a su usuario a la parte superior de la página ( que, para mi sorpresa, es un comportamiento específico ). Probablemente debería apuntar a algún lugar que funcione sin javascript.

Si el enlace realmente solo tiene sentido con javascript (como los controles para una presentación de diapositivas solo js o algo así), creo que es mejor agregar el enlace a la página con javascript. Alternativamente, si realmente desea ponerlo en su fuente, asegúrese de que sea display:none'd' por defecto. Drupal tiene la .jsclase en el html para luego mostrarla cuando javascript está disponible.

Stephen Tweeddale
fuente
7

Desafortunadamente, la url()función (que l()llama internamente) prácticamente elimina cualquier posibilidad de un fragmento vacío con las siguientes líneas:

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

Comprueba para asegurarse de que el fragmento no sea una cadena vacía, que es lo que necesita pasar para obtener la limpieza #. Creo que la solución más fácil sería elegir la identificación de un elemento adecuado en algún lugar de la página y usarla para el fragmento (o javascript:voidcomo Sithu ha mencionado).

Sin embargo ... la forma más accesible (y posteriormente, en muchos países, de manera legal; piense en la sección 508 en los Estados Unidos, el DDA en el Reino Unido, etc.) sería proporcionar el contenido que se carga / ajusta mediante su enlace en una página separada, y use la URL de esa página como href del enlace en su lugar. Luego usaría javascript para evitar que el evento en el enlace redirija realmente la página para aquellos navegadores que lo tienen habilitado.

De esta forma, tiene contenido de respaldo para usuarios sin javascript, se mantiene legal y mantiene contentos a todos y a sus perros :)

Clive
fuente
¡Gran edición sobre reserva! Si usamos la URL de ajax en href del enlace, ¿puede la página de llamada ser un HTML representable si javascript está deshabilitado? Alguna vez tuve print drupal_json_output($output)en mi página de llamadas ajax.
Sithu
4

No puedes usar clean #.

Pero es posible agregar space symboldespués de #:

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

Simplemente tuve el mismo problema, pero ninguna de las soluciones fue satisfactoria, así que se me ocurrió la mía:

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

Esto produce una limpieza #

<a href="#">link</a>
David Sidler
fuente
Cerca, esto produce <a href="# ">link</a>para mí.
tyler.frankenstein
1

En su lugar, usaría el tipo de representación html_tag porque creo que el enlace de representación recibe atención especial de Drupal. La desventaja es que no hay una función de atajo, por lo que tendremos que usar una matriz de renderizado:

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

Esta es básicamente la misma respuesta que publiqué aquí ... La configuración fragmenten un solo espacio se convertirá en a #, y $current_pathse incluye porque de lo contrario, el enlace se establecerá en www.example.com/#lugar de www.example.com/current-page#:

$current_path = check_url(drupal_get_path_alias($_GET['q']));
$link = l('link', $current_path, array('fragment' => ' '));
jerdiggity
fuente
No es necesario obtener el alias de ruta porque l () se convertirá en alias por usted. En realidad, es preferible utilizar una ruta sin alias.
rooby