vertical regresa problemas desplazamiento con barra javascript jquery resize scrollbar

javascript - problemas - barra de desplazamiento se regresa



Detecta cuando aparece la barra de desplazamiento vertical de la ventana (6)

La primicia

Es posible detectar cambios en la visibilidad de la barra de desplazamiento utilizando ResizeObserver para verificar los cambios en el tamaño del elemento que puede tomar las barras de desplazamiento y los cambios en el tamaño de su contenido.

Razón fundamental

Comencé a implementar una solución con el método <iframe> pero rápidamente descubrí que tener una implementación completa requería romper la separación de las preocupaciones entre las vistas de mi aplicación. Tengo una vista principal que necesita saber cuándo una vista secundaria adquiere una barra de desplazamiento vertical. (No me importa la barra de desplazamiento horizontal.) Tengo dos situaciones que pueden afectar la visibilidad de la barra de desplazamiento vertical:

  1. La vista principal se redimensiona. Esto está bajo el control directo del usuario.

  2. El contenido de la vista infantil se vuelve más grande o más pequeño. Esto está bajo control indirecto del usuario. La vista secundaria muestra los resultados de una búsqueda. La cantidad y el tipo de resultados determinan el tamaño de la vista secundaria.

Descubrí que si usaba <iframe> , tendría que usar la vista secundaria para respaldar las necesidades de los padres. Prefiero que el niño no contenga código para algo que es puramente una preocupación de los padres. Con la solución que describo aquí, solo era necesario modificar la vista principal.

Entonces, al buscar una mejor solución, encontré esta respuesta de Daniel Herr. Sugiere usar ResizeObserver para detectar cuándo cambian las dimensiones de un div. ResizeObserver todavía no está disponible de forma nativa en todos los navegadores, pero hay un robusto relleno / relleno de relleno que utilizo para el soporte en casos donde el soporte nativo no está disponible. (Aquí está la spec para ResizeObserver ).

Prueba de concepto

Yo uso este polyfill en su modo ponyfill. De esa manera, el entorno global permanece intacto. Esta implementación se basa en window.requestAnimationFrame , y recurrirá a setTimeout para plataformas que no son compatibles con window.requestAnimationFrame . Mirando el soporte para requestAnimationFrame en "¿Puedo usar ...?", Lo que veo allí no me molesta. YMMV.

Tengo una proof-of-concept vivo. La clave es escuchar los cambios de tamaño en el elemento DOM que puede aceptar barras de desplazamiento (el elemento con container ID, en verde) y escuchar los cambios de tamaño en el contenido que puede necesitar desplazamiento (el elemento con content identificación). La prueba de concepto utiliza interact.js para administrar un elemento de ajuste (con identificador de resizer , en azul) que permite cambiar el tamaño del container . Si arrastra la esquina inferior derecha del resizer , cambiará el tamaño del resizer y el container . Los dos botones permiten simular cambios en el tamaño de los contenidos mostrados por el container .

Estoy usando este método en un código que se encuentra actualmente en una etapa de prelanzamiento, lo que significa que pasó las pruebas en varios navegadores y que las partes interesadas lo están evaluando, pero aún no está en producción.

El HTML:

<!DOCTYPE html> <html> <head> <script data-require="interact.js@*" data-semver="1.0.26" src="//rawgit.com/taye/interact.js/v1.0.26/interact.js"></script> <script src="//rawgit.com/que-etc/resize-observer-polyfill/master/dist/ResizeObserver.global.js"></script> <link rel="stylesheet" href="style.css" /> </head> <body> <div id="resizer"> <div id="container"> <ul id="content"> <li>Something</li> </ul> </div> </div> <button id="add">Add to content</button> <button id="remove">Remove from content</button> <p>Scroll bar is: <span id="visibility"></span></p> <ul id="event-log"></ul> <script src="script.js"></script> </body> </html>

El JavaScript:

var container = document.getElementById("container"); var resizer = document.getElementById("resizer"); interact(resizer) .resizable({ restrict: { restriction: { left: 0, top: 0, right: window.innerWidth - 10, bottom: window.innerHeight - 10 } } }) .on(''resizemove'', function(event) { var target = resizer; var rect = target.getBoundingClientRect(); var width = rect.width + event.dx; var height = rect.height + event.dy; target.style.width = width + ''px''; target.style.height = height + ''px''; }); var content = document.getElementById("content"); var add = document.getElementById("add"); add.addEventListener("click", function() { content.insertAdjacentHTML("beforeend", "<li>Foo</li>"); }); var remove = document.getElementById("remove"); remove.addEventListener("click", function() { content.removeChild(content.lastChild); }); // Here is the code that pertains to the scrollbar visibility var log = document.getElementById("event-log"); content.addEventListener("scrollbar", function () { log.insertAdjacentHTML("beforeend", "<li>Scrollbar changed!</li>"); }); var visiblity = document.getElementById("visibility"); var previouslyVisible; function refreshVisibility() { var visible = container.scrollHeight > container.clientHeight; visibility.textContent = visible ? "visible" : "not visible"; if (visible !== previouslyVisible) { content.dispatchEvent(new Event("scrollbar")); } previouslyVisible = visible; } // refreshVisibility(); var ro = new ResizeObserver(refreshVisibility); ro.observe(container); ro.observe(content);

El CSS:

* { box-sizing: border-box; } #container { position: relative; top: 10%; left: 10%; height: 80%; width: 80%; background: green; overflow: auto; } #resizer { background: blue; height: 200px; width: 200px; }

¿Aparece / desaparece una solución simple y confiable para detectar la ventana de la barra de desplazamiento vertical?

window.onresize no se activa cuando la página de manipulación DOM de JavaScript se vuelve lo suficientemente alta como para aparecer la barra de desplazamiento.

En esta publicación muy similar Detecte si una página tiene una solución de barra de desplazamiento vertical que describe cómo detectar si la barra de desplazamiento está presente o no, pero necesito saber exactamente cuándo aparece.


Basado en la respuesta de OrganicPanda, surgió esta cosa jquery

$(''<iframe id="scrollbar-listener"/>'').css({ ''position'' : ''fixed'', ''width'' : ''100%'', ''height'' : 0, ''bottom'' : 0, ''border'' : 0, ''background-color'' : ''transparent'' }).on(''load'',function() { var vsb = (document.body.scrollHeight > document.body.clientHeight); var timer = null; this.contentWindow.addEventListener(''resize'', function() { clearTimeout(timer); timer = setTimeout(function() { var vsbnew = (document.body.scrollHeight > document.body.clientHeight); if (vsbnew) { if (!vsb) { $(top.window).trigger(''scrollbar'',[true]); vsb=true; } } else { if (vsb) { $(top.window).trigger(''scrollbar'',[false]); vsb=false; } } }, 100); }); }).appendTo(''body'');

Esto desencadenará eventos de ''barra de desplazamiento'' en la ventana, si aparecen / desaparecen

Funciona en Chrome / Mac, al menos. ahora, alguien extiende esto para detectar barras de desplazamiento horizontales :-)


Detectar dinámicamente el evento barra de desplazamiento vertical del navegador comparando window.innerWidth con getBoundingClientRect () de un elemento DIV utilizando Javascript. Probado con el último IE FF Chrome. Ver documentación here


Perdón por traer esto de vuelta a la muerte, pero acabo de correr hacia esta limitación y se me ocurrió mi propia solución. Es un poco raro, pero quédate conmigo ...

La idea es agregar un iframe invisible de 100% de ancho a la página y escuchar los eventos de cambio de tamaño en su ventana interna. Estos eventos detectarán cambios no solo en el tamaño de la ventana exterior sino también cuando las barras de desplazamiento se agreguen o eliminen de la ventana externa.

Activa un evento de cambio de tamaño de ventana normal, por lo que no requiere código adicional si ya está escuchando el cambio de tamaño de la ventana.

Probado en IE9 y último en Chrome / Firefox, podría funcionar en IEs más antiguas, pero mi proyecto no es compatible, por lo que no lo he intentado.

https://gist.github.com/OrganicPanda/8222636


Si está utilizando AngularJS, puede usar una directiva para detectar cuándo cambia el ancho (suponiendo que la barra de desplazamiento que aparece / desaparece es vertical):

app.directive(''verticalScroll'', function($rootScope){ return { restrict: ''A'', link: function (scope, element) { scope.$watch( function() { return element[0].clientWidth; }, function() { $rootScope.$emit(''resize''); } ); } } });

Esto dispara un evento en el alcance raíz que otras directivas o controladores pueden escuchar.

El reloj se dispara con el ciclo de resumen angular, por lo que depende de que Angular haya cargado / eliminado el contenido adicional que ha provocado que la barra de desplazamiento aparezca / desaparezca.


Window.onresize no funcionará, porque la ventana no está cambiando de tamaño.

body.onresize no funcionará, ya que el cambio de resize solo se implementa para ventanas y marcos.

Esta pregunta tiene que ver con el mismo problema. El que responde primero tiene algunas ideas interesantes, aunque ninguna simple, o navegador cruzado.

Creo que este enfoque basado en Jquery de Rick Strahl es lo mejor que se puede obtener: Monitoreo de los cambios CSS de elementos HTML en JavaScript . Utiliza las funciones de "vigilancia" del navegador si están disponibles, o un temporizador si no es así. Este último no es muy amigable con los recursos pero parece que no hay forma de evitarlo.

Una buena forma de cómo decirle a la barra de desplazamiento una vez que se resuelva el cambio de resize está en esta pregunta por cierto, en caso de que no se esté refiriendo a esa en su pregunta.