Горизонтальный стиль меню Medium.com - см. Пример Pi c - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь сделать так, чтобы моя система меню выглядела точно так же, как и у среды, однако мне просто не удается заставить стрелки отображаться слева и справа от самого меню. Как показано в примере изображения, или вы можете просмотреть его здесь

div.scrollmenu {
  /*   background-color: #333; */
  overflow: auto;
  white-space: nowrap;
}

div.scrollmenu a {
  display: inline-block;
  color: black;
  text-align: center;
  padding: 14px;
  text-decoration: none;
}


/* div.scrollmenu a:hover {
  background-color: #777;
} */
<div class="scrollmenu">
  <a href="#home">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  <a href="#about">About</a>
  <a href="#support">Support</a>
  <a href="#blog">Blog</a>
  <a href="#tools">Tools</a>
  <a href="#base">Base</a>
  <a href="#custom">Custom</a>
  <a href="#more">More</a>
  <a href="#logo">Logo</a>
  <a href="#friends">Friends</a>
  <a href="#partners">Partners</a>
  <a href="#people">People</a>
  <a href="#work">Work</a>
</div>

Ответ на стрелки - это то, что я ищу, и буду признателен. Пример изображения

1 Ответ

0 голосов
/ 10 июля 2020

Неважно, я работал над своим ответом. В любом случае, спасибо, мой ответ ниже, и я надеюсь, что это ответит на чей-то вопрос в будущем:

var SETTINGS = {
  navBarTravelling: false,
  navBarTravelDirection: "",
  navBarTravelDistance: 150
}

var colours = {
  0: "#867100",
  1: "#7F4200",
  2: "#99813D",
  3: "#40FEFF",
  4: "#14CC99",
  5: "#00BAFF",
  6: "#0082B2",
  7: "#B25D7A",
  8: "#00FF17",
  9: "#006B49",
  10: "#00B27A",
  11: "#996B3D",
  12: "#CC7014",
  13: "#40FF8C",
  14: "#FF3400",
  15: "#ECBB5E",
  16: "#ECBB0C",
  17: "#B9D912",
  18: "#253A93",
  19: "#125FB9",
}

document.documentElement.classList.remove("no-js");
document.documentElement.classList.add("js");

// Out advancer buttons
var pnAdvancerLeft = document.getElementById("pnAdvancerLeft");
var pnAdvancerRight = document.getElementById("pnAdvancerRight");
// the indicator
var pnIndicator = document.getElementById("pnIndicator");

var pnProductNav = document.getElementById("pnProductNav");
var pnProductNavContents = document.getElementById("pnProductNavContents");

pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));

// Set the indicator
moveIndicator(pnProductNav.querySelector("[aria-selected=\"true\"]"), colours[0]);

// Handle the scroll of the horizontal container
var last_known_scroll_position = 0;
var ticking = false;

function doSomething(scroll_pos) {
  pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));
}

pnProductNav.addEventListener("scroll", function() {
  last_known_scroll_position = window.scrollY;
  if (!ticking) {
    window.requestAnimationFrame(function() {
      doSomething(last_known_scroll_position);
      ticking = false;
    });
  }
  ticking = true;
});


pnAdvancerLeft.addEventListener("click", function() {
  // If in the middle of a move return
  if (SETTINGS.navBarTravelling === true) {
    return;
  }
  // If we have content overflowing both sides or on the left
  if (determineOverflow(pnProductNavContents, pnProductNav) === "left" || determineOverflow(pnProductNavContents, pnProductNav) === "both") {
    // Find how far this panel has been scrolled
    var availableScrollLeft = pnProductNav.scrollLeft;
    // If the space available is less than two lots of our desired distance, just move the whole amount
    // otherwise, move by the amount in the settings
    if (availableScrollLeft < SETTINGS.navBarTravelDistance * 2) {
      pnProductNavContents.style.transform = "translateX(" + availableScrollLeft + "px)";
    } else {
      pnProductNavContents.style.transform = "translateX(" + SETTINGS.navBarTravelDistance + "px)";
    }
    // We do want a transition (this is set in CSS) when moving so remove the class that would prevent that
    pnProductNavContents.classList.remove("pn-ProductNav_Contents-no-transition");
    // Update our settings
    SETTINGS.navBarTravelDirection = "left";
    SETTINGS.navBarTravelling = true;
  }
  // Now update the attribute in the DOM
  pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));
});

pnAdvancerRight.addEventListener("click", function() {
  // If in the middle of a move return
  if (SETTINGS.navBarTravelling === true) {
    return;
  }
  // If we have content overflowing both sides or on the right
  if (determineOverflow(pnProductNavContents, pnProductNav) === "right" || determineOverflow(pnProductNavContents, pnProductNav) === "both") {
    // Get the right edge of the container and content
    var navBarRightEdge = pnProductNavContents.getBoundingClientRect().right;
    var navBarScrollerRightEdge = pnProductNav.getBoundingClientRect().right;
    // Now we know how much space we have available to scroll
    var availableScrollRight = Math.floor(navBarRightEdge - navBarScrollerRightEdge);
    // If the space available is less than two lots of our desired distance, just move the whole amount
    // otherwise, move by the amount in the settings
    if (availableScrollRight < SETTINGS.navBarTravelDistance * 2) {
      pnProductNavContents.style.transform = "translateX(-" + availableScrollRight + "px)";
    } else {
      pnProductNavContents.style.transform = "translateX(-" + SETTINGS.navBarTravelDistance + "px)";
    }
    // We do want a transition (this is set in CSS) when moving so remove the class that would prevent that
    pnProductNavContents.classList.remove("pn-ProductNav_Contents-no-transition");
    // Update our settings
    SETTINGS.navBarTravelDirection = "right";
    SETTINGS.navBarTravelling = true;
  }
  // Now update the attribute in the DOM
  pnProductNav.setAttribute("data-overflowing", determineOverflow(pnProductNavContents, pnProductNav));
});

pnProductNavContents.addEventListener(
  "transitionend",
  function() {
    // get the value of the transform, apply that to the current scroll position (so get the scroll pos first) and then remove the transform
    var styleOfTransform = window.getComputedStyle(pnProductNavContents, null);
    var tr = styleOfTransform.getPropertyValue("-webkit-transform") || styleOfTransform.getPropertyValue("transform");
    // If there is no transition we want to default to 0 and not null
    var amount = Math.abs(parseInt(tr.split(",")[4]) || 0);
    pnProductNavContents.style.transform = "none";
    pnProductNavContents.classList.add("pn-ProductNav_Contents-no-transition");
    // Now lets set the scroll position
    if (SETTINGS.navBarTravelDirection === "left") {
      pnProductNav.scrollLeft = pnProductNav.scrollLeft - amount;
    } else {
      pnProductNav.scrollLeft = pnProductNav.scrollLeft + amount;
    }
    SETTINGS.navBarTravelling = false;
  },
  false
);

// Handle setting the currently active link
pnProductNavContents.addEventListener("click", function(e) {
  var links = [].slice.call(document.querySelectorAll(".pn-ProductNav_Link"));
  links.forEach(function(item) {
    item.setAttribute("aria-selected", "false");
  })
  e.target.setAttribute("aria-selected", "true");
  // Pass the clicked item and it's colour to the move indicator function
  moveIndicator(e.target, colours[links.indexOf(e.target)]);
});

// var count = 0;
function moveIndicator(item, color) {
  var textPosition = item.getBoundingClientRect();
  var container = pnProductNavContents.getBoundingClientRect().left;
  var distance = textPosition.left - container;
  var scroll = pnProductNavContents.scrollLeft;
  pnIndicator.style.transform = "translateX(" + (distance + scroll) + "px) scaleX(" + textPosition.width * 0.01 + ")";
  // count = count += 100;
  // pnIndicator.style.transform = "translateX(" + count + "px)";

  if (color) {
    pnIndicator.style.backgroundColor = color;
  }
}

function determineOverflow(content, container) {
  var containerMetrics = container.getBoundingClientRect();
  var containerMetricsRight = Math.floor(containerMetrics.right);
  var containerMetricsLeft = Math.floor(containerMetrics.left);
  var contentMetrics = content.getBoundingClientRect();
  var contentMetricsRight = Math.floor(contentMetrics.right);
  var contentMetricsLeft = Math.floor(contentMetrics.left);
  if (containerMetricsLeft > contentMetricsLeft && containerMetricsRight < contentMetricsRight) {
    return "both";
  } else if (contentMetricsLeft < containerMetricsLeft) {
    return "left";
  } else if (contentMetricsRight > containerMetricsRight) {
    return "right";
  } else {
    return "none";
  }
}

/**
 * @fileoverview dragscroll - scroll area by dragging
 * @version 0.0.8
 * 
 * @license MIT, see https://github.com/asvd/dragscroll
 * @copyright 2015 asvd <heliosframework@gmail.com> 
 */


(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['exports'], factory);
  } else if (typeof exports !== 'undefined') {
    factory(exports);
  } else {
    factory((root.dragscroll = {}));
  }
}(this, function(exports) {
  var _window = window;
  var _document = document;
  var mousemove = 'mousemove';
  var mouseup = 'mouseup';
  var mousedown = 'mousedown';
  var EventListener = 'EventListener';
  var addEventListener = 'add' + EventListener;
  var removeEventListener = 'remove' + EventListener;
  var newScrollX, newScrollY;

  var dragged = [];
  var reset = function(i, el) {
    for (i = 0; i < dragged.length;) {
      el = dragged[i++];
      el = el.container || el;
      el[removeEventListener](mousedown, el.md, 0);
      _window[removeEventListener](mouseup, el.mu, 0);
      _window[removeEventListener](mousemove, el.mm, 0);
    }

    // cloning into array since HTMLCollection is updated dynamically
    dragged = [].slice.call(_document.getElementsByClassName('dragscroll'));
    for (i = 0; i < dragged.length;) {
      (function(el, lastClientX, lastClientY, pushed, scroller, cont) {
        (cont = el.container || el)[addEventListener](
          mousedown,
          cont.md = function(e) {
            if (!el.hasAttribute('nochilddrag') ||
              _document.elementFromPoint(
                e.pageX, e.pageY
              ) == cont
            ) {
              pushed = 1;
              lastClientX = e.clientX;
              lastClientY = e.clientY;

              e.preventDefault();
            }
          }, 0
        );

        _window[addEventListener](
          mouseup, cont.mu = function() {
            pushed = 0;
          }, 0
        );

        _window[addEventListener](
          mousemove,
          cont.mm = function(e) {
            if (pushed) {
              (scroller = el.scroller || el).scrollLeft -=
                newScrollX = (-lastClientX + (lastClientX = e.clientX));
              scroller.scrollTop -=
                newScrollY = (-lastClientY + (lastClientY = e.clientY));
              if (el == _document.body) {
                (scroller = _document.documentElement).scrollLeft -= newScrollX;
                scroller.scrollTop -= newScrollY;
              }
            }
          }, 0
        );
      })(dragged[i++]);
    }
  }


  if (_document.readyState == 'complete') {
    reset();
  } else {
    _window[addEventListener]('load', reset, 0);
  }

  exports.reset = reset;
}));
* {
  box-sizing: inherit;
}

.pn-ProductNav_Wrapper {
  position: relative;
  padding: 0 11px;
  box-sizing: border-box;
}

.pn-ProductNav {
  /* Make this scrollable when needed */
  overflow-x: auto;
  /* We don't want vertical scrolling */
  overflow-y: hidden;
  /* For WebKit implementations, provide inertia scrolling */
  -webkit-overflow-scrolling: touch;
  /* We don't want internal inline elements to wrap */
  white-space: nowrap;
  /* If JS present, let's hide the default scrollbar */
  /* positioning context for advancers */
  position: relative;
  font-size: 0;
}

.js .pn-ProductNav {
  /* Make an auto-hiding scroller for the 3 people using a IE */
  -ms-overflow-style: -ms-autohiding-scrollbar;
  /* Remove the default scrollbar for WebKit implementations */
}

.js .pn-ProductNav::-webkit-scrollbar {
  display: none;
}

.pn-ProductNav_Contents {
  float: left;
  -webkit-transition: -webkit-transform 0.2s ease-in-out;
  transition: -webkit-transform 0.2s ease-in-out;
  transition: transform 0.2s ease-in-out;
  transition: transform 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
  position: relative;
}

.pn-ProductNav_Contents-no-transition {
  -webkit-transition: none;
  transition: none;
}

.pn-ProductNav_Link {
  text-decoration: none;
  color: #888;
  font-size: 1.2rem;
  font-family: -apple-system, sans-serif;
  display: -webkit-inline-box;
  display: inline-flex;
  -webkit-box-align: center;
  align-items: center;
  min-height: 44px;
  border: 1px solid transparent;
  padding: 0 11px;
}

.pn-ProductNav_Link+.pn-ProductNav_Link {
  border-left-color: #eee;
}

.pn-ProductNav_Link[aria-selected="true"] {
  color: #111;
}

.pn-Advancer {
  /* Reset the button */
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: transparent;
  padding: 0;
  border: 0;
  /* Now style it as needed */
  position: absolute;
  top: 0;
  bottom: 0;
  /* Set the buttons invisible by default */
  opacity: 0;
  -webkit-transition: opacity 0.3s;
  transition: opacity 0.3s;
}

.pn-Advancer:focus {
  outline: 0;
}

.pn-Advancer:hover {
  cursor: pointer;
}

.pn-Advancer_Left {
  left: 0;
}

[data-overflowing="both"]~.pn-Advancer_Left,
[data-overflowing="left"]~.pn-Advancer_Left {
  opacity: 1;
}

.pn-Advancer_Right {
  right: 0;
}

[data-overflowing="both"]~.pn-Advancer_Right,
[data-overflowing="right"]~.pn-Advancer_Right {
  opacity: 1;
}

.pn-Advancer_Icon {
  width: 20px;
  height: 44px;
  fill: #bbb;
}

.pn-ProductNav_Indicator {
  position: absolute;
  bottom: 0;
  left: 0;
  height: 4px;
  width: 100px;
  background-color: transparent;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  -webkit-transition: background-color 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
  transition: background-color 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
  transition: transform 0.2s ease-in-out, background-color 0.2s ease-in-out;
  transition: transform 0.2s ease-in-out, background-color 0.2s ease-in-out, -webkit-transform 0.2s ease-in-out;
}
<div class="pn-ProductNav_Wrapper">
  <nav id="pnProductNav" class="pn-ProductNav">
    <div id="pnProductNavContents" class="pn-ProductNav_Contents">
      <a href="#" class="pn-ProductNav_Link" aria-selected="true">Chairs</a>
      <a href="#" class="pn-ProductNav_Link">Tables</a>
      <a href="#" class="pn-ProductNav_Link">Cookware</a>
      <a href="#" class="pn-ProductNav_Link">Beds</a>
      <a href="#" class="pn-ProductNav_Link">Desks</a>
      <a href="#" class="pn-ProductNav_Link">Flooring</a>
      <a href="#" class="pn-ProductNav_Link">Lighting</a>
      <a href="#" class="pn-ProductNav_Link">Mattresses</a>
      <a href="#" class="pn-ProductNav_Link">Solar Panels</a>
      <a href="#" class="pn-ProductNav_Link">Bookcases</a>
      <a href="#" class="pn-ProductNav_Link">Mirrors</a>
      <a href="#" class="pn-ProductNav_Link">Rugs</a>
      <a href="#" class="pn-ProductNav_Link">Curtains &amp; Blinds</a>
      <a href="#" class="pn-ProductNav_Link">Frames &amp; Pictures</a>
      <a href="#" class="pn-ProductNav_Link">Wardrobes</a>
      <a href="#" class="pn-ProductNav_Link">Storage</a>
      <a href="#" class="pn-ProductNav_Link">Decoration</a>
      <a href="#" class="pn-ProductNav_Link">Appliances</a>
      <a href="#" class="pn-ProductNav_Link">Racks</a>
      <a href="#" class="pn-ProductNav_Link">Worktops</a>
      <span id="pnIndicator" class="pn-ProductNav_Indicator"></span>
    </div>
  </nav>
  <button id="pnAdvancerLeft" class="pn-Advancer pn-Advancer_Left" type="button">
        <svg class="pn-Advancer_Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 551 1024"><path d="M445.44 38.183L-2.53 512l447.97 473.817 85.857-81.173-409.6-433.23v81.172l409.6-433.23L445.44 38.18z"/></svg>
    </button>
  <button id="pnAdvancerRight" class="pn-Advancer pn-Advancer_Right" type="button">
        <svg class="pn-Advancer_Icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 551 1024"><path d="M105.56 985.817L553.53 512 105.56 38.183l-85.857 81.173 409.6 433.23v-81.172l-409.6 433.23 85.856 81.174z"/></svg>
    </button>
</div>

You can also view my demo on codepen where I worked it up at.
<p /> https://codepen.io/REthinkify/pen/KKVezJL
...