每次单击按钮时向右/向左移动

时间:2015-11-22 14:27:13

标签: jquery css jquery-animate css-transforms timeline

我正试图制作一个“时间表”。我这样做是为了更多地了解jquery,所以我试图不使用任何“timeline js plugins”。

我使用jQuery函数来集中用户点击的Event。我是通过使用转换来实现的:

$('.tl-container').css('transform', 'translateX(' + movingDistance + 'px)');

然后我添加了几个箭头,这样用户就可以左右移动,看看可能看不见的其他事件。

我怎样才能让按钮在每次点击时将时间轴移动100px?

我首先尝试使用翻译的想法,但这不起作用。它会翻译一次,但第二次点击将不再起作用(因为时间轴已经在翻译的“结束”。

然后我尝试使用.animate()。这有效,但有一个主要问题。它“抵消”整个时间轴,所以当我点击一个事件时它不会居中(它将移动到新的“偏移中心”。

有什么想法吗?

这是一个显示我现在拥有的CodePen: https://codepen.io/anon/pen/bVJQbB

如果您愿意,我也有GitHug上的项目: https://github.com/boguz/chronos

1 个答案:

答案 0 :(得分:1)

我已经分叉了你的笔:https://codepen.io/sodawillow/pen/MaRZLa

在HTML中我添加了两个带有nextprev ID的按钮(仅用于测试目的,因为当我第一次使用笔时,你的箭头没有显示在Firefox上):

<button id="prev">prev</button>
<button id="next">next</button>

在JS中,我添加了一个全局变量(activeEventNumber)来保存当前活动事件,并将其与代码一起使用,将光标向前或向后模式化一步。当然,这可以稍微改善一下:

$("#prev").on("click", prevEvent);
$("#next").on("click", nextEvent);

function prevEvent() {
  var eventSize = $('.tl-event').width(),
    windowSize = $(window).width(),
    clickedPosition = eventSpacing * --activeEventNumber + eventSize * activeEventNumber,
    movingDistance = windowSize / 2 - clickedPosition - eventSpacing / 2 - eventSpacing * 1.7;
  $('.tl-container').css('transform', 'translateX(' + movingDistance + 'px)');
  activeEvent($(".tl-event").eq(activeEventNumber - 1));
}

function nextEvent() {
  var eventSize = $('.tl-event').width(),
    windowSize = $(window).width(),
    clickedPosition = eventSpacing * ++activeEventNumber + eventSize * activeEventNumber,
    movingDistance = windowSize / 2 - clickedPosition - eventSpacing / 2 - eventSpacing * 1.7;
  $('.tl-container').css('transform', 'translateX(' + movingDistance + 'px)');
  activeEvent($(".tl-event").eq(activeEventNumber - 1));
}

PS:我会尝试用笔来改进JS

编辑:我的笔有你的箭和我的工作,我尽可能地干掉JS(比你的JS少的线:))。我也添加了键盘箭头。如果您不理解某些/任何事情,请告诉我。

// Use Strict Mode
"use strict";

// GLOBAL variables
var eventSpacing = 50, activeEventNumber = 0, clickedEventNumber, eventSize, windowSize;

// DOCUMENT READY FUNCTION
$(function () {
  
  //set useful values
  clickedEventNumber = $(this).index();
  eventSize = $('.tl-event').width();
  windowSize = $(window).width();

  createTimeline();
  initEvents();

}); // end of document.ready

function createTimeline() {
  var numberOfEvents = $('.tl-event').length;
  
  $('.tl-line').each(function() {
    var lineLength = numberOfEvents * (eventSpacing + eventSize);
    $('.tl-container').css('width', lineLength + (eventSpacing * 2) +'px');
    $('.tl-line').css('left', eventSpacing + 'px');
    $('.tl-line').css('width', lineLength + 'px');
  });
  
  $('.tl-event').each(function() {
    var eventNumber = $(this).index();
    var eventHorPosition = eventNumber * eventSpacing + eventSpacing / 2;
    $(this).css('left', eventHorPosition + 'px');
  });
}

function initEvents() {
  
  //click
  $('.tl-event').on('click', function() {
    activeEventNumber = $(this).index();
    moveCursor(activeEventNumber);    
  });
  
  //buttons
  $('#prev, .arrow-before').on("click", moveToPrevEvent);
  $('#next, .arrow-after').on("click", moveToNextEvent);
  
  //keyboard arrows
  $(window).on("keydown", function(e) {
    switch(e.which) {
      case 37: moveToPrevEvent(); break; //left arrow key
      case 39: moveToNextEvent(); break; //right arrow key
      default: return; // exit this handler for other keys
    }
    e.preventDefault(); // prevent the default action (scroll / move caret)
  });
  
  //next and previous functions
  function moveToPrevEvent() { if(activeEventNumber > 1) moveCursor(--activeEventNumber); } 
  function moveToNextEvent() { if(activeEventNumber < $('.tl-event').length) moveCursor(++activeEventNumber); }

  //main function to select an event
  function moveCursor(eventNumber) {
    var clickedPosition, movingDistance;  
    //move
    clickedPosition = (eventSpacing + eventSize) * eventNumber;
    movingDistance = windowSize / 2 - clickedPosition - eventSpacing * 2.2; //magic number ! :) 1.7 + .5
    $('.tl-container').css('transform', 'translateX(' + movingDistance + 'px)');
    //style
    $('.tl-event').css('background-color', 'white');
    $($(".tl-event").eq(activeEventNumber - 1)).css('background-color', 'red');
  }
}
* {
  margin: 0;
  padding: 0;
}

body {
  background-color: #444;
  color: #fff;
  max-width: 100%;
  overflow: hidden;
  text-align: center;
}


.tl-mask {
  border: 1px solid red;
  height: 200px;
  width: 86vw;
  margin: 10vh auto 0;
  overflow: hidden;
  position: relative;
}
.arrow {
  height: 40px;
  position: absolute;
  top: 188px;
  opacity: .2;
}
.arrow:hover {
  opacity: .75;
  cursor: pointer;
}
.arrow-before {
  left: 50px;
}
.arrow-after {
  right: 50px;
}
.tl-container {
  height: 200px;
  background-color: #666;
  position: relative;
  transition: all 2s ease;
  min-width: 100%;
}
.tl-line {
  background-color: white;
  height: 2px;
  display: block;
  position: relative;
  top: 100px;
}
.tl-event {
  background-color: white;
  height: 10px;
  width: 10px;
  position: relative;
  top: 94px;
  border-radius: 50%;
  float: left;
}
.tl-event:hover {
  cursor: pointer;
}

.center-check {
  background-color: white;
  width: 3px;
  height: 20px;
  margin: 10px auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>chronos</h1>
<img src="./img/arrow_before.png" alt="" class="arrow arrow-before">

<div class="tl-mask">
  <div class="tl-container">
    <div class="tl-line"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
    <div class="tl-event"></div>
  </div> <!-- end .tl-container -->
</div> <!-- end -tl-mask -->

<img src="./img/arrow_after.png" alt="" class="arrow arrow-after">
<div class="center-check"></div>

<button id="prev">prev</button>
<button id="next">next</button>