Recuerdo los primeros días de JavaScript en los que necesitaba una función simple para casi todo porque los proveedores de navegadores implementaban las funciones de manera diferente, y no solo las funciones de borde, las funciones básicas, como addEventListener
y attachEvent
. Los tiempos han cambiado, pero todavía hay algunas funciones que cada desarrollador debe tener en su arsenal, para el rendimiento con fines de facilidad funcional.
Debounce
La función de rebote puede ser un cambio de juego cuando se trata de un desempeño impulsado por eventos. Si no está utilizando una función de supresión de rebotes con un scroll
, resize
, key*
caso, es probable que haciendo mal. Aquí hay una debounce
función para mantener su código eficiente:
// Devuelve una función, que, mientras se siga invocando, // no se activará. Se llamará a la función cuando deje de llamarse durante // N milisegundos. Si se pasa `inmediato`, active la función en el // borde de ataque, en lugar del final. función de rebote ( func , espera , inmediata ) { var timeout ; return function ( ) { var context = this , args = argumentos ; var later = function () { timeout = null ; si ( ! inmediato ) func . aplicar ( contexto , argumentos ) ; } ; var callNow = inmediato && ! tiempo de espera ; clearTimeout ( timeout ) ; timeout = setTimeout ( más tarde , espera ) ; if ( callNow ) func . aplicar (contexto , args ) ; } ; } ; // Uso var myEfficientFn = debounce ( function ( ) { // Todo lo que grava , } 250 ) ; ventana . addEventListener ( ' resize ' , myEfficientFn ) ;
La debounce
función no permitirá que una devolución de llamada se utilice más de una vez en un período de tiempo determinado. Esto es especialmente importante cuando se asigna una función de devolución de llamada a eventos que se activan con frecuencia.
Poll
Como mencioné con la debounce
función, a veces no puede conectarse a un evento para indicar un estado deseado. Si el evento no existe, debe verificar su estado deseado a intervalos:
// La función de la función de sondeo poll ( fn , timeout , interval ) { var endTime = Number ( new Date ( ) ) + ( timeout || 2000 ) ; intervalo = intervalo || 100 ; var checkCondition = function ( resolver , rechazar ) { // ¡Si se cumple la condición, hemos terminado! resultado var = fn ( ) ; if ( resultado ) { resolver ( resultado ) ; } // Si la condición no se cumple pero el tiempo de espera no ha transcurrido, vaya otra vez si ( Número ( nueva Fecha ( ) ) < endTime ) { setTimeout (checkCondition , intervalo , resolver , rechazar ) ; } // No coinciden y demasiado tiempo, rechazar! else { reject ( nuevo Error ( 'se agotó el tiempo de espera para' + fn + ':' + argumentos ) ) ; } } ; devolver nueva promesa ( checkCondition ) ; } // Uso: asegúrese de que el elemento sea visible poll ( function ( ) { return document . GetElementById ( 'lightbox' ) . OffsetWidth > 0 ; } , 2000 , 150 ) . luego ( function ( ) { // Polling hecho, ahora haz otra cosa! } ) . catch ( function ( ) { // Polling time out out, maneja el error! } ) ;
¡El sondeo siempre ha sido útil en la web y seguirá siendo en el futuro!
Once
Hay ocasiones en las que prefiere que una funcionalidad determinada solo ocurra una vez, de manera similar a como usaría un onload
evento. Este código le proporciona dicha funcionalidad:
función una vez ( fn , contexto ) { var resultado ; función de retorno ( ) { si ( fn ) { resultado = fn . aplicar ( contexto || esto , argumentos ) ; fn = nulo ; } volver resultado ; } ; } // Uso var canOnlyFireOnce = once ( function ( ) { console . Log ( 'Fired!' ) ; } ) ; canOnlyFireOnce ( ) ; // "¡Despedido!" canOnlyFireOnce ( ) ; // nada
La once
función garantiza que una función determinada solo se pueda llamar una vez, por lo tanto, ¡evita la inicialización duplicada!
GetAbsoluteUrl
Obtener una URL absoluta de una cadena variable no es tan fácil como parece. URL
Está el constructor, pero puede actuar si no proporciona los argumentos necesarios (que a veces no puede). Aquí hay un truco suave para obtener una URL absoluta de y entrada de cadena:
var getAbsoluteUrl = ( function ( ) { var a ; función de retorno ( url ) { si ( ! a ) a = documento . createElement ( 'a' ) ; una . href = url ; devuelve un . href ; } ; } ) ( ) ; // Uso getAbsoluteUrl ( '/ something' ) ; // https://davidwalsh.name/something
Los elementos de «quemar» se href
manejan y la URL no tiene sentido para usted, proporcionando a cambio una URL absoluta confiable.
IsNative
Saber si una función dada es nativa o no puede indicar si está dispuesto a anularla. Este código útil puede darle la respuesta:
; ( función ( ) { // Se utiliza para resolver el `[[Class]]` interno de los valores var toString = Object . prototipo . toString ; // Se utiliza para resolver la fuente de funciones descompilada var fnToString = Function . prototipo . toString ; // Se utiliza para detectar constructores de host (Safari> 4; realmente específico de matriz tipada ) var reHostCtor = / ^ \ [object. +? Constructor \] $ / ; // Compilar una expresión regular utilizando un método nativo común como plantilla. // Escogimos `Object # toString` porque hay una buena probabilidad de que no esté siendo superado. var reNative = RegExp ( '^' + // Coerce `Object # toString` a una cadena String ( toString ) // Escape cualquier carácter de expresión regular especial . replace ( / [. * +? ^ $ {} () | [\] \ / \\] / g , '\\ $ &' ) // Reemplace las menciones de `toString` con`. *? `para mantener la plantilla genérica. // Reemplace algo como` para ... `para admitir entornos como Rhino que añaden información adicional // como aridad método. . reemplace( / toString | (function). *? (? = \\\ () | for. +? (? = \\\]) / g , '$ 1. *?' ) + '$' ) ; la función esNativa ( valor ) { var type = typeof value ; devuelva type == 'function' // Use `Function # toString` para omitir el propio método` toString` del valor // y evite que lo falsifiquen. ? reNative . test ( fnToString . call ( value ) ) // Retroceder a una verificación de objeto de host porque algunos entornos representarán // cosas como matrices escritas como métodos DOM que pueden no ajustarse al // patrón nativo normal. : ( valor&& escriba == 'objeto' && reHostCtor . test ( toString . call ( value ) ) ) || falsa ; } // exportar como quieras el modulo . exportaciones = esNativo ; } ( ) ) ; // Uso esNativo ( alerta ) ; // true isNative ( myCustomFunction ) ; // falso
¡La función no es bonita pero hace el trabajo!
InsertRule
Todos sabemos que podemos tomar un NodeList de un selector (vía document.querySelectorAll
) y darle a cada uno un estilo, pero lo que es más eficiente es establecer ese estilo en un selector (como lo hace en una hoja de estilo):
var sheet = ( function ( ) { // Cree la etiqueta <style> var style = document . createElement ( 'style' ) ; // ¡Agrega un medio (y / o consulta de medios) aquí si quieres! // style.setAttribute ('media', 'screen') // style.setAttribute ('media', 'pantalla única y (ancho máximo: 1024px)') // WebKit hack :( estilo . AppendChild ( documento . CreateTextNode ( '' ) ) ; // Añadir el elemento <style> al documento de la página . la cabeza . appendChild ( estilo ) ; devolver el estilo . hoja ; } ) ( ) ; // Hoja de uso . insertRule ( "header {float: left; opacity: 0.8;}" , 1 ) ;
Esto es especialmente útil cuando se trabaja en un sitio dinámico de AJAX. Si establece el estilo en un selector, no necesita tener en cuenta el estilo de cada elemento que puede coincidir con ese selector (ahora o en el futuro).
MatchesSelector
A menudo validamos la entrada antes de seguir adelante; garantizar un valor real, garantizar que los datos de formularios sean válidos, etc. Pero, ¿con qué frecuencia nos aseguramos de que un elemento califique para avanzar? Puede usar una matchesSelector
función para validar si un elemento es de una coincidencia de selector dada:
función matchesSelector ( el , selector ) { var p = Elemento . prototipo ; var f = p . coincidencias || p . webkitMatchesSelector || p . mozMatchesSelector || p . msMatchesSelector || función ( es ) { retorno [ ] . indexOf . llamar ( documento .querySelectorAll ( s ) , this ) ! == - 1 ; } ; volver f . llamada ( el , selector ) ; } // Uso matchesSelector ( documento . GetElementById ( 'myDiv' ) , 'div.someSelector [algunos-atributo = true]' )
Te esperamos en los siguientes artículos en donde hablaremos mas acerca de estos temas, los cuales hoy en día son de vital importancia en el mundo de la tecnología.