javascript - vertical - que es la barra de desplazamiento en windows




¿Cómo detectar en qué lado del navegador está la barra de desplazamiento-derecha o izquierda(en caso de RTL)? (5)

Para <html dir="rtl"> algunos navegadores (Safari, Edge, IE) moverán automáticamente la barra de desplazamiento hacia el lado izquierdo, que es el comportamiento correcto:

Desafortunadamente, los principales navegadores (Chrome y Firefox) se están comportando de una manera diferente, la barra de desplazamiento todavía está en el lado derecho del navegador.

¿Es posible detectar mediante programación (preferiblemente con vainilla JS) en qué lado está la barra de desplazamiento?

UPD (28.09.2018): hasta ahora, no hay una solución funcional en las respuestas, la gente está tratando de detectar la posición de la barra de desplazamiento utilizando getBoundingClientRect().left .offsetLeft o .offsetLeft y eso no funcionará porque siempre estará 0 al menos en Borde independientemente de la posición de la barra de desplazamiento.

UPD (15.10.2018): TLDR: no hay manera.

Parece que los navegadores no proporcionan API para la detección del lado de la barra de desplazamiento. En las respuestas a continuación hay trucos con la inserción de un div ficticio y el cálculo de dónde está la barra de desplazamiento en ese div. No puedo considerar esos trucos como una respuesta porque la barra de desplazamiento del documento se puede colocar de varias maneras ( <html dir="rtl"> , versión RTL del SO, configuración del navegador, etc.)


Como se muestra here , la barra de desplazamiento no cambiará de lado con dir="rtl" en html o etiqueta HTML de body en Firefox, Chrome, Opera y Safari. Funciona en IE y Edge. Lo intenté (en Edge 17, IE 11, Firefox 62, Chrome 69, Opera 56, Safari 5.1) y aún es relevante en octubre de 2018 (Safari> 9.1 muestra la barra de desplazamiento en el lado izquierdo si dir="rtl" ).

No encontré ninguna solución nativa de navegador cruzado hasta ahora para encontrar la posición de la barra de desplazamiento como pediste. No creo que tengas uno. Solo podemos tratar de encontrar "hackear" para arreglarlo ...

Basándome en sus preguntas / comentarios y en su problema real here , creo que sería mejor centrarse en la compatibilidad de dir="rtl" . Está intentando averiguar la posición de la barra de desplazamiento porque, en primer lugar, no estaba funcionando como se esperaba. Para que funcione como se esperaba, una solución rápida podría ser colocar el rollo en el elemento del body :

<!DOCTYPE html>
<html dir="rtl">
  <head>
    <meta charset="utf-8">
    <title></title>
    <style>
      html, body {
        height: 100%;
        overflow: hidden;
      }

      body {
        padding: 0;
        margin: 0;
        overflow-y: auto; /* or overflow: auto; */
      }

      p {
        margin: 0;
        font-size: 8em;
      }
    </style>
  </head>

  <body>

    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
      dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

  </body>
</html>

Este código css hará que el elemento del body desplace en lugar del elemento html . Extrañamente, coloque el desplazamiento en el body para mostrar la barra de desplazamiento en el lugar correcto. Funciona para las versiones recientes de los navegadores.

La compatibilidad exacta es (versión de trabajo más antigua probada):

  • IE => v6 - 2001
  • Edge => all
  • Firefox => v4 - 2011
  • Opera => v10 - 2009
  • Chrome => v19 - 2012
  • Safari => v10.1 - 2016

Con los navegadores compatibles, puede "confiar" en la posición de la barra de desplazamiento según el atributo dir . Significa que para los navegadores listados arriba, la barra de desplazamiento estará a la izquierda para dir="rtl" y a la derecha para dir="ltr" . He probado y funciona.

Para versiones anteriores de navegadores, no tengo una solución por el momento. Significa que no serás totalmente compatible, pero es principalmente un problema con el safari, como puedes ver.

EDITAR: Investigación para encontrar la posición de la barra de desplazamiento

Como mencioné anteriormente, creo que podemos intentar encontrar un "truco" para encontrar la posición de la barra de desplazamiento. No soy un experto en css, por lo que mi solución no es muy bonita. Alguien con habilidades css probablemente podría encontrar una buena solución.

Si el desplazamiento está en el cuerpo (solución anterior), podemos detectar la posición de la barra de desplazamiento con el elemento posicionado css. Por ejemplo este código:

<!DOCTYPE html>
<html dir="rtl">
<head>
  <meta charset="utf-8">
  <title></title>
  <style>
    html, body {
      height: 100%;
      overflow: hidden;
    }

    body {
      padding: 0;
      margin: 0;
      overflow-y: auto;
    }

    p {
      margin: 0;
      font-size: 8em;
    }

    #sc { position: relative; float: left; }
    #sc_2 { position: relative; float: right; }
    #sc_3 { position: absolute; width: 100%; }
  </style>
</head>
<body>
  <div id="sc"></div>
  <div id="sc_2"></div>
  <div id="sc_3"></div>
  
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
  tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
  quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
  consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
  cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
  proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

  <script>
    var html = document.getElementsByTagName('html')[0];
    var sc = document.getElementById('sc');
    var sc_2 = document.getElementById('sc_2');
    var sc_3 = document.getElementById('sc_3');

    if (sc_2.offsetLeft < html.clientWidth && !(sc_3.offsetLeft < 0)) {
      console.log('bar on the right');
    } else if (sc.offsetLeft > 0 || sc_3.offsetLeft < 0) {
      console.log('bar on the left');
    } else {
      console.log('no bar');
    }
  </script>
</body>
</html>

La compatibilidad es (versión de trabajo más antigua probada):

  • IE => v6 - 2001
  • Edge => all
  • Firefox => v4 - 2011
  • Opera => v10 - 2009
  • Chrome => v15 - 2011
  • Safari => no funciona

Esta solución no es muy útil si el desplazamiento está en la etiqueta del body porque como se mencionó anteriormente en este caso, podemos "confiar" en el atributo dir . Lo puse aquí porque probablemente podría adaptarse para el desplazamiento en la etiqueta html .


La barra de desplazamiento es parte del elemento del cuerpo, no podrá "inspeccionar" un elemento que no sea HTML.


La solución a esta pregunta tal vez sea muy innovadora, tengo una idea:

  1. Declaro una función de JavaScript para devolver la posición izquierda de un elemento a todo el documento.
  2. Declaro otra función para hacer visibility: hidden elemento visibility: hidden como div dentro del cuerpo y su nombre es parent .
  3. Creo otra división dentro de la div principal, la div child y luego calculo la posición secundaria a la izquierda con mi función en el # 1.
  4. Configuré overflow-y: scroll a la div principal y recalculo la posición izquierda de la div secundaria.
  5. Si la segunda posición calculada del niño disminuía, significa que la barra de desplazamiento está en el lado derecho. si se incrementa significa que la barra de desplazamiento está en el lado izquierdo. si no aparecen cambios, significa que no hay ninguna barra de desplazamiento como Mac OSX navegadores Mac OSX con un trackpad o un mouse mágico.

Ver código abajo:

function leftOffset(el) {
  const rect = el.getBoundingClientRect();
  const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
  return rect.left + scrollLeft;
}

La función anterior solo calcula la posición izquierda, ahora vea los códigos a continuación para comprender el lado de la barra de desplazamiento de su navegador:

function getScrollbarSide() {
  const parent = document.createElement('div'); // parent
  parent.style.visibility = 'hidden';
  parent.style.width = '100px';
  parent.style.height = '50px';
  parent.style.position = 'relative';

  const child = document.createElement('div'); // child
  child.style.width = '1px';
  child.style.height = '1px';
  child.style.position = 'absolute';
  child.style.left = '50%';

  document.body.appendChild(parent);
  parent.appendChild(child);

  const leftOffsetNoScroll = leftOffset(child); // calculate left offset of child without parent scrollbar
  parent.style.overflowY = 'scroll';

  const leftOffsetWithScroll = leftOffset(child); // calculate left offset of child with parent scrollbar

  const calc = leftOffsetNoScroll - leftOffsetWithScroll;

  if (calc > 0) {
    return 'right';
  }
  if (calc < 0) {
    return 'left';
  }
  return 'no-scrollbar';
}

Ahora, simplemente ejecute getScrollbarSide() .


Mejoré en la answer Andre :

Todo lo que necesitas es getComputedStyle()

console.clear();

const btn = document.querySelector('Button');
const html = document.querySelector('html');
const wrap = document.querySelector('#myBodyWrapper');
const input = document.querySelector('input');

var state = 'ltr';
var inner = '';

for (var i = 0; i < 500; i++) {
  inner += 'Lorem ipsum Bla bla bla<br>';
}
wrap.innerHTML = inner;

btn.addEventListener('click', function() {
  toggleDirection(html)
}, false);


function getDirection(elem) {
  return window.getComputedStyle(elem).direction
}
function setDirection(elem, direction) {
  elem.setAttribute('dir', direction)
}
function toggleDirection(elem) {
  if (getDirection(elem) === 'ltr' || getDirection(elem) === undefined) {
    setDirection(elem, 'rtl')
  } else {
    setDirection(elem, 'ltr')
  }
  input.value = getDirection(elem)
}

input.value = getDirection(html)
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  text-align: center;
}

div#myBodyWrapper {
  overflow: auto;
  height: 80vh;
  text-align: start;
  margin: 10px 40px;
  padding: 10px;
  background-color: goldenrod;
}
button {
  background-color:gold;
  padding:5px;
  margin:5px 0;
}

input {
  background-color: silver;
  text-align: center;
  padding: 5px;
  font-size: 20px;
}
<button>Switch scrollbar</button><br>
<input type="text" value="">
<div id="myBodyWrapper"></div>


Que yo sepa, no hay manera de hacer eso. Sin embargo, puede forzar la Barra de desplazamiento hacia el lado izquierdo si la envuelve en un DIV desplazable. No estoy seguro de si eso es lo que quieres, pero funciona. (Funciona en mi máquina: solo pude probarlo en Firefox, Chrome y Safari en Mac)

Puedes controlar la barra de desplazamiento con CSS. Cambiar la propiedad de direction también cambiará la barra de desplazamiento. Y en Javascript puedes reaccionar a todos los eventos o cambios de atributos o lo que quieras.

Aquí hay un Boilerplate para jugar con

const btn = document.querySelector('Button');
const html = document.querySelector('html');
const wrap = document.querySelector('#myBodyWrapper');
let state = 'ltr';
var inner = '';
for (let i = 0; i < 500; i++) {
  inner += 'Lorem ipsum Bla bla bla<br>';
}
wrap.innerHTML = inner;
btn.addEventListener('click', function() {
  state = (state === 'ltr') ? 'rtl' : 'ltr';
  wrap.style.direction = state;
}, false);
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

div#myBodyWrapper {
  direction: ltr;
  overflow: auto;
  height: 100vh;
  width: 100vw;
}
button{
    background-color:gold;
    padding:5px;
    margin:5px 0;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <button>Switch scrollbar</button>
  <div id="myBodyWrapper">

  </div>

</body>

</html>

Ahora puedes controlar la barra de desplazamiento con CSS. Y en Javascript puedes reaccionar a todos los eventos o cambios de atributos o lo que quieras. Es posible que desee utilizar un mutationObserver en el elemento HTML si desea cambiar el atributo dir y luego reaccionar a eso.





hebrew