Как подставить значение, полученное JS, в конкретное место в CSS? - PullRequest
0 голосов
/ 04 марта 2019

И CSS, и JS читают с внешними файлами.


Что я хочу сделать:

.typ-wrap::-webkit-scrollbar-track-piece:end {
margin-right: ?px;
background: transparent;
}
.typ-wrap::-webkit-scrollbar-track-piece:start {
margin-left: ?px;
background: transparent;
}

Я хотел бы включить значение, полученное вычитанием 302px из этого ?.
В формулу ? = (Window size) - 302px / 2 (? это то же значение)

like this


То, что я пробовал (последняя версия) (не работало):

$(function() {
   var typscrollWidth = $('.typ::after').width();   // get 302px
   var windowWidth = $(window).innerWidth();
   var typthumbCenter = windowWidth - typscrollWidth / 2;   //the above formula

   $('.typ-wrap::-webkit-scrollbar-track-piece:end').css('margin-right', 
     typthumbCenter + 'px');
   $('.typ-wrap::-webkit-scrollbar-track-piece:start').css('margin-left', 
     typthumbCenter + 'px');
});

Я нашел пример, который кажется нестандартным, так что это jQuery ..
Но я хочу писать на JavaScript.
(Извините, Энди, я до сих пор не понимаюкак это сделать с переменными в моем примере ..: '()

Почему не CSS? Потому что эффект, который я пытаюсь сделать, не может быть достигнут с помощью автоматической настройки CSS (например, margin: auto;)..

Я не так много понимаю JS: (
В таком случае, как мне писать?
Кто-то, пожалуйста, помогите мне!


Добавить

При загрузке каждый раз она немного смещается. Как только она изменит ширину окна, она будет правильной.
Знаете ли вы, почему?

like this


Код

Соответствующий кодпосередине.
Фрагмент кода выглядит правильно, когда он заполнен на всю страницу.(Поскольку теперь это ручная настройка, только для среды с шириной окна 1280 пикселей)

html {font-size: 62.5%;}
body {margin: 0; padding: 0; border: 0; outline: 0; font-size: 100%; vertical-align: baseline; background: transparent; box-sizing: border-box; list-style-type: none;}    /* reset */

.typ {
  position: relative;
  width: 100%;
 }
 .typ::after {
  content: '';
  position: absolute;
  z-index: -1;
  width: 30.2rem;    /* Place of 302px */
  height: 1.6rem;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  background: url("https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228080150.png");
 }

.typ-wrap {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  margin-bottom: 8.3rem;
  overflow-x: scroll;
  overflow-y: hidden;
  writing-mode: bt-lr;
  /* IE */
  -webkit-appearance: none;
 }
.typ-wrap::-webkit-scrollbar {
  display: block;
  width: 33.2rem;
 }
.typ-wrap::-webkit-scrollbar-track {
  -webkit-appearance: none;
  background: transparent;
 }
 
 /*  from here  */ 
.typ-wrap::-webkit-scrollbar-track-piece:end {
  margin-right: 489px;    /* It's centered in Fullpage (In my environment) */
  background: transparent;
 }
.typ-wrap::-webkit-scrollbar-track-piece:start {
  margin-left: 489px;    /* It's centered in Fullpage (In my environment lol) */
  background: transparent;
 }
 /*  to here  */

.typ-wrap::-webkit-scrollbar-thumb {
  width: 1.5rem;
  height: 1.3rem;
  background: #fff;
  border: 1px solid #000;
 }
.typ-wrap ul {
  width: 100%;
  height: 31.9rem;
  white-space: nowrap;
 }
.typ-wrap li {
  display: inline-block;
 }
.typ-wrap li:first-child {
  margin-left: 3rem;
 }
.typ-wrap li:last-child {
  margin-right: 3rem;
 }
.typ-wrap li + li {
  margin-left: 3rem;
 }
<div class="typ">
  <div class="typ-wrap">
   <ul>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075715.png" alt="あ=a" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075712.png" alt="い=b" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075710.png" alt="う=c" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075706.png" alt="え=d" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075704.png" alt="お=e" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075810.png" alt="か=f" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075807.png" alt="き=g" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075805.png" alt="く=h" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075802.png" alt="け=i" /></a>
     </li>
     <li>
       <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075759.png" alt="こ=j" /></a>
     </li>
   </ul>
  </div>
</div>

1 Ответ

0 голосов
/ 04 марта 2019

Без полной HTML трудно помочь столько, сколько я хотел бы.Основная идея состоит в том, чтобы использовать CSS-переменные и обновить переменную от наших JavaScript слушателей.

Вот пример, который обновляет ширину элемента .typ-wrap до половины размера области просмотра.

// Check on load
checkWindowWidth();

// Check on resize
$(window).on('resize', handleResize);

function handleResize() {
  checkWindowWidth();
}

function checkWindowWidth() {
  $(":root")[0].style.setProperty('--window-width', $(window).width());
  $('.typ-wrap').attr('data-window-width', $(window).width());
}
html,
body {
  margin: 0;
}

:root {
  --window-width: 0;
}

.typ-wrap {
  display: inline-block;
  width: calc(var(--window-width) / 2 * 1px);
  height: 50px;
  background: green;
  position: relative;
}

.typ-wrap::after {
  content: attr(data-window-width) 'px';
  position: absolute;
  bottom: -1.5em;
  left: 50%;
  transform: translateX(-50%);
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="typ-wrap" data-window-width=""></div>

Обновление (решение!)

Глядя на страницу MDN для пользовательской полосы прокрутки, яне видел упоминаний о :end и :start в качестве суффикса к ::-webkit-scrollbar-track-piece, что заставило меня задуматься: почему бы не установить вместо этого оба поля? Так вот, что я и сделал.

CSS Я добавил:

.typ-wrap::-webkit-scrollbar-track-piece {
  margin-left: calc(((var(--window-width) * 1px) - 302px) / 2);
  margin-right: calc(((var(--window-width) * 1px) - 302px) / 2);
  …
}

В нашем JavaScript мы устанавливаем ширину окна как для загрузки страницы, так и для события изменения размера.

$(":root")[0].style.setProperty('--window-width', $(window).innerWidth());

Демо (только Chrome):

// Check on load
checkWindowWidth();

// Check on resize
$(window).on('resize', handleResize);

function handleResize() {
  checkWindowWidth();
}

function checkWindowWidth() {
  $(":root")[0].style.setProperty('--window-width', $(window).innerWidth());
}
:root {
  --window-width: 0;
}

html {
  font-size: 62.5%;
}

body {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  font-size: 100%;
  vertical-align: baseline;
  background: transparent;
  box-sizing: border-box;
  list-style-type: none;
}

/* reset */

.typ {
  position: relative;
  width: 100%;
}

.typ::after {
  content: '';
  position: absolute;
  z-index: -1;
  width: 30.2rem;
  height: 1.6rem;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  background: url("https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228080150.png");
}

.typ-wrap {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  margin-bottom: 8.3rem;
  overflow-x: scroll;
  overflow-y: hidden;
  writing-mode: bt-lr;
  -webkit-appearance: none;
}

.typ-wrap::-webkit-scrollbar {
  display: block;
  width: 33.2rem;
}

.typ-wrap::-webkit-scrollbar-track {
  -webkit-appearance: none;
  background: transparent;
}

.typ-wrap::-webkit-scrollbar-track-piece {
  margin-left: calc(((var(--window-width) * 1px) - 302px) / 2);
  margin-right: calc(((var(--window-width) * 1px) - 302px) / 2);
  background: transparent;
}

.typ-wrap::-webkit-scrollbar-thumb {
  width: 1.5rem;
  height: 1.3rem;
  background: #fff;
  border: 1px solid #000;
}

.typ-wrap ul {
  width: 100%;
  height: 31.9rem;
  white-space: nowrap;
}

.typ-wrap li {
  display: inline-block;
}

.typ-wrap li:first-child {
  margin-left: 3rem;
}

.typ-wrap li:last-child {
  margin-right: 3rem;
}

.typ-wrap li+li {
  margin-left: 3rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="typ">
  <div class="typ-wrap">
    <ul>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075715.png"
                 alt="あ=a" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075712.png"
                 alt="い=b" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075710.png"
                 alt="う=c" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075706.png"
                 alt="え=d" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075704.png"
                 alt="お=e" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075810.png"
                 alt="か=f" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075807.png"
                 alt="き=g" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075805.png"
                 alt="く=h" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075802.png"
                 alt="け=i" /></a>
      </li>
      <li>
        <a href=""><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/O/O2_milk/20190228/20190228075759.png"
                 alt="こ=j" /></a>
      </li>
    </ul>
  </div>

Обновление II (Некоторое объяснение)

Итак, какого черта эта строка в любом случае?

margin-left: calc(((var(--window-width) * 1px) - 302px) / 2);

Это CSS, но довольно вложенный и сложный вид.Это не так уж плохо.Давайте разберемся с этим.

calc()

Думайте об этом как об умном калькуляторе для Интернета.Он встроен в CSS и может сделать для нас несколько хитрых вещей, таких как add 41em + 50px.Большинство людей не могут вычислить это вне своей головы, но это не проблема для calc().Так же, как настоящий калькулятор, вы можете выполнять несколько операций одновременно.

Единственное предостережение в том, что по обе стороны от ваших операторов должен существовать пробел (+, -, *, /).

Хорошо

calc(40% + 5px);

Плохо

calc(40%+5px);

Теперь у нас есть эта часть выражения:

((var(--window-width) * 1px)

Давайте пойдем наизнанку.Ниже приводится число, которое мы генерируем с помощью JavaScript, как при первой загрузке, так и после изменения размера.

var(--window-width)

Дело в том, что число не имеет единиц измерения в конце.Это может быть 511, но не 511px.Это приводит нас к следующей части этого длинного уравнения, где мы умножаем ширину без единиц измерения * 1px.Помните, когда я говорил, что calc() может принимать совершенно разные единицы и объединять их в одно значение?Ну, умножив на 1px, я заставляю эту ширину равняться px width.

Теперь, когда у нас есть ширина окна в формате px, мы вычитаем 302px изэто, константа из вашего уравнения.Наконец, мы берем результат из всего этого и делим его на 2, учитывая половину ширины самой полосы прокрутки.Теперь у нас есть динамически центрированная полоса прокрутки, готовая к действию.

Хорошо, переведите дыхание.Чтобы ответить на ваш последний вопрос, я считаю, что небольшой сдвиг, который вы иногда видите, сводится к аномалиям субпиксельного рендеринга, которые могут возникать в браузере при заданной ширине экрана.Иногда я вижу сдвиг, но не всегда.Вероятно, это зависит от того, когда произошло событие изменения размера и насколько точны эти окончательные расчеты.Я бы связал это с трудностью решения проблем, возникающих при таком динамическом позиционировании элементов, которое иногда перезапускается каждую секунду.Я не уверен, что смогу решить эту последнюю часть без гораздо большего расследования и работы.

Я надеюсь, что через весь этот вопрос вы узнали несколько вещей.Может быть, вы можете помочь кому-нибудь в будущем.Подобные вопросы делают участие в этом сайте увлекательным.Приятно познакомиться, POP!

jsFiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...