seccion pagina otra link especifica animado animadas anclas ancla jquery html jquery-selectors css-selectors fragment-identifier

jquery - pagina - scroll ancla js



¿Por qué “#.id” es un selector incorrecto en CSS/jQuery pero funciona en un ancla HTML? (5)

¿Por qué el propio navegador acepta este ancla pero jQuery y querySelector no lo hacen?

Debido a que el hash no es un selector de CSS, es un # seguido de una ID.

El navegador se desplaza felizmente hacia ese elemento porque no está utilizando el hash, sin cambios, como un selector de CSS. Probablemente no utilice un selector de CSS en absoluto, sino su método interno para buscar elementos por ID, el que también es llamado por document.getElementById , que tampoco se preocupa por el punto. Prueba:

document.getElementById(".someMethodName").style.color = "green";

<div id=".someMethodName">I''m green because I was found by <code>document.getElementById(".someMethodName")</code></div>

Si bien es cierto que CSS usa un # para marcar el comienzo de un selector de ID, eso no significa que cada # todas partes sea el comienzo de un selector de ID de CSS.

Si el navegador usara el hash como un selector de CSS, presumiblemente lo escaparía correctamente antes de usarlo.

Estoy usando JSDoc. Genera ids con un periodo como en

<a id=".someMethodName"></a>

Si otra parte de la página tiene

<a href="#.someMethodName"></a>

Eso funciona perfectamente. Al hacer clic en el segundo ancla se desplaza al primero.

Pero, ni document.querySelector ni jQuery encontrarán el ancla.

¿Por qué el propio navegador acepta este ancla pero jQuery y querySelector no lo hacen?

test("document.querySelector(''#.someMethodName'')", function() { document.querySelector(''#.someMethodName''); }); test("$(''#.someMethodName'')", function() { $(''#.someMethodName''); }); function test(msg, fn) { try { var result = fn(); log(msg, result); } catch(e) { log(msg, e); } } function log() { var pre = document.createElement("pre"); pre.appendChild(document.createTextNode(Array.prototype.join.call(arguments, " "))); document.body.appendChild(pre); }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <a href="#.someMethodName">click here to go to anchor and see errors</a> <pre> put some text here so the page is long enough that when we click the anchor the browser has as a place to scroll that is off screen otherwise we''d have no way to see if it worked or not </pre> <a id=".someMethodName">we should scroll to here</a> <p>did we make it?</p> <hr/>


Respecto a las convenciones de nombres de identificadores HTML5

En HTML5, puede asignar un HTML5 sintaxis o sin restricciones en la sintaxis:

No hay otras restricciones sobre qué forma puede tomar una identificación; en particular, las ID pueden constar de solo dígitos, comenzar con un dígito, comenzar con un guión bajo, constar de solo puntuación, etc.


¿Qué funciones de selector están esperando?

Sin embargo, cuando se utilizan selectores de JavsScript como Document.querySelector() , es importante tener en cuenta la sintaxis de cómo evalúa sus argumentos.

Devuelve el primer elemento dentro del documento (mediante el recorrido previo a la orden de profundidad primero de los nodos del documento | por el primer elemento en el marcado del documento y la iteración a través de nodos secuenciales por orden de cantidad de nodos secundarios) que coincida con el grupo especificado de selectores.

element = document.querySelector (selectores);

  • element es un objeto de elemento.
  • selectors es una cadena que contiene uno o más selectores de CSS separados por comas.


Cuando confundes las funciones del selector

Así que aquí, vemos que está intentando analizar los selectores de CSS . Básicamente, la función interpreta cualquier cadena que comience con un # como clase y cualquier cadena que comience con un # como id , así que cuando intentas pasar una cadena como esta:

#.someMethodName

Piensa que estás tratando de analizar un id y una clase como un solo argumento, y lanza un error llamándolo un error de sintaxis.


En conclusión

Entonces, en conclusión, mientras que sus valores de ID son técnicamente válidos, usar . y # confundirá esas funciones de selector de JavaScript como $(selector) y document.querySelector(selector) etc.

Para solucionar este problema, debe informar a la función que está tratando de usar . o # como un carácter en lugar de un identificador escapando los caracteres que no son identificadores:

#//.someMethodName

Demostración de trabajo de este en acción.


HTML5 permite tener un punto en un valor de atributo de ID, y los navegadores han manejado esto sin problemas durante décadas (por lo que la restricción en HTML 4, definida en sí misma no por HTML sino por SGML en la que se basa) se relajó en HTML5. ahora libre del equipaje legado de SGML). Entonces el problema no está en el valor del atributo.

La gramática de un identificador de fragmento como se define en RFC 3986 es:

fragment = *( pchar / "/" / "?" )

Donde el conjunto de caracteres de pchar incluye el punto. Entonces .someMethodName es un identificador de fragmento válido, por lo que <a href="#.someMethodName"> funciona.

Pero #.someMethodName no es un selector válido, y la razón es doble:

  1. Un selector de ID consta de un # seguido de un ident, y un ident en CSS no puede contener un punto .
  2. Por lo tanto, el período se reserva para un selector de clase (que de manera similar consiste en un período seguido de un ident).

En resumen, el analizador está esperando un identificador de CSS después del # pero no encuentra uno debido al . Eso lo sigue directamente, haciendo que el selector sea inválido. Esto es sorprendente porque la notación de un selector de ID se basa, de hecho, en la notación URI para un identificador de fragmento, como lo demuestra el hecho de que ambos comienzan con un signo # , así como el hecho de que ambos se usan para hacer referencia. un elemento identificado de forma única en el documento por ese identificador. No es irrazonable esperar que cualquier cosa que funcione en un fragmento de URI también funcione en un selector de ID, y en la mayoría de los casos es cierto. Pero como CSS tiene su propia gramática que no se correlaciona necesariamente con la gramática URI (porque son dos estándares 1 no relacionados), se obtienen casos de vanguardia como este.

Como el período es parte del identificador de fragmento, deberá escapar con una barra invertida para usarlo en un selector de ID:

#/.someMethodName

No olvide que necesita escapar de la barra invertida dentro de una cadena de JavaScript (por ejemplo, para usar con document.querySelector() y jQuery):

document.querySelector(''#//.someMethodName'') $(''#//.someMethodName'')

1 Hace varios años, se formó un Grupo de la Comunidad W3C (del cual soy miembro) en torno a una propuesta conocida como Uso de los selectores de CSS como identificadores de fragmentos que, como pueden imaginar, combinaron las dos tecnologías de una manera interesante. Sin embargo, esto nunca despegó, y las únicas implementaciones conocidas son algunas extensiones de navegador que probablemente ni siquiera se mantengan.


Para HTML5 es un atributo de id válido:

No hay otras restricciones sobre qué forma puede tomar una identificación ; en particular, las ID pueden constar de solo dígitos, comenzar con un dígito, comenzar con un guión bajo, constar de solo puntuación, etc.

Ya que no es un identificador de CSS válido, para usarlo con querySelector() o $() debe escapar de este modo:

#//.someMethodName

Red de Desarrolladores de Mozilla :

Para hacer coincidir la ID o los selectores que no siguen la sintaxis de CSS (por ejemplo, utilizando dos puntos o un espacio de manera inadecuada), debe escapar del carácter con una barra invertida . Como la barra diagonal inversa es un carácter de escape en JavaScript, si ingresa una cadena literal, debe hacerlo dos veces (una vez para la cadena JavaScript y otra vez para querySelector):

Sea consciente de que no es un atributo de ID de HTML4 válido


Tienes que escapar con // antes de consultar por elementos. Reemplazar

document.querySelector(''#.someMethodName'');

A

document.querySelector(''#//.someMethodName'');

También tenga en cuenta que técnicamente, para HTML4 , el formato del valor de ID requerido se especifica a continuación:

Los tokens de ID y NOMBRE deben comenzar con una letra ([A-Za-z]) y pueden ir seguidos de cualquier número de letras, dígitos ([0-9]), guiones ("-"), guiones bajos ("_") , dos puntos (":") y puntos (".").

Entonces, .[A-Za-z] no es válido uno ..