jQuery更改活动的div onClick以及上一个下一个

时间:2018-08-14 23:36:15

标签: jquery

我已经使用jQuery和CSS构建了一个自定义的交互式svg地图。当我单击地图标记时,一切都可以完美运行,它添加/删除了类以显示/隐藏相关内容。现在,我尝试添加一个新功能,即“上一个”和“下一个”按钮,以允许用户以其他方式更改位置。我有点喜欢它,但是单击几下后,它就会粘起来,并选择了错误的div。到目前为止,这是我所拥有的(一些用于地图标记而非所有多边形点的示例代码):

<div id="map-nav">
  <a class="button prev-tab">Previous</a>
  <a class="button next-tab">Next</a>
</div>

<div class="map">
  <svg>
    <g data-dive="1" class="map-marker current">1</g>
    <g data-dive="2" class="map-marker">2</g>
    <g data-dive="3" class="map-marker">3</g>
  </svg>
</div>

<div id="1" class="map-content current">Content 1</div>
<div id="2" class="map-content">Content 2</div>
<div id="3" class="map-content">Content 3</div>

还有Jquery:

// Jquery Map
  $('.map-marker').click(function(){
        var dive_id = $(this).attr('data-dive');

        $('.map-marker').removeClass('current');
        $('.map-content').removeClass('current');

        $(this).addClass('current');
        $("#"+dive_id).addClass('current');
    });

  // Jquery Map Next Button
  $('.next-tab').click(function() {
   // get current tab
   var currentTab = $('.map-marker.current');
   var currentMap = $('.map-content.current');

   // get the next tab, if there is one
   var newTab = currentTab.next();
   var newMap = currentMap.prev();

   // at the end, so go to the first one
   if (newTab.length === 0) {
     newTab = $('.map-marker').first();
   }
   if (newMap.length === 0) {
     newMap = $('.map-content').first();
   }

   currentTab.removeClass('current');
   currentMap.removeClass('current');
   // add active to new tab
   newTab.addClass('current');
   newMap.addClass('current');
 });

 // Jquery Map Prev Button
 $('.prev-tab').click(function() {
   // get current tab
   var currentTab = $('.map-marker.current');
   var currentMap = $('.map-content.current');

   // get the previous tab, if there is one
   var newTab = currentTab.prev();
   var newMap = currentMap.prev();

   // at the start, so go to the last one
   if (newTab.length === 0) {
     newTab = $('.map-marker').last();
   }
   if (newMap.length === 0) {
     newMap = $('.map-content').last();
   }

   currentTab.removeClass('current');
   currentMap.removeClass('current');
   // add active to new tab
   newTab.addClass('current');
   newMap.addClass('current');
 });

正如我所说,通过单击标记来更改标记/内容的第一次单击功能非常有效。其下一个和上一个按钮无法正常工作。我也相信可能有更好的方法来实现下一个和上一个按钮,但这是我想出的。任何改进的建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

我建议使用自己的索引通过map-content对象的列表进行简单迭代。这样可以避免代码直接依赖于您拥有的HTML标记来增加灵活性。

提供的代码段还可以处理任意数量的标记,它们会被自动拾取,因此您不必手动列出它们。

$(function() {
  //Slide IDs
  var slides = [];
  //Get all markers from the map and put them to array
  $('svg > .map-marker').each(function() {
    slides.push($(this).attr('data-dive'));
  });
  //Index of currently displayed slide
  var currentSlide = 0;
  //Show the inital slide
  $('.map-content').hide();
  $('#' + slides[currentSlide]).show();

  //Click on markers on the map will show the specific slide
  $('.map-marker').on('click', function() {
    //First we get the data-dive attribute
    let diveId = $(this).attr('data-dive');
    //Now we hide all content items shown
    $('.map-content').hide();
    //And show the chosen one
    $('#' + diveId).show();
    //And set the current slide to that value so the next and prev buttons
    //can navigate from that point
    currentSlide = slides.indexOf(diveId);
    return false;
  });

  //Click on each button does basically the same,
  //except the direction of the move
  $('a.next-tab, a.prev-tab').on('click', function() {
    //We check whether or not we clicked on next or prev and increase
    //or decrease the slide number accordingly
    if ($(this).hasClass('prev-tab')) currentSlide--;
    else currentSlide++;
    //Next we check for the boundaries and adjust it accordingly
    if (currentSlide < 0) currentSlide = slides.length - 1;
    if (currentSlide >= slides.length) currentSlide = 0;
    //Hide all shown content items
    $('.map-content').hide();
    //Show the next(or prev) one
    $('#' + slides[currentSlide]).show();
    return false;
  });
})
div.map-content {
  display: none;
  border: 1px solid black;
  border-radius: 5px;
  min-height: 100px;
}

.map-marker {
  cursor: pointer;
}

div.current {
  display: block;
}

.map {
  width: 150px;
  height: 50px;
  margin: 20px 0 20px 0;
  background-color: green;
}

a.button {
  display: inline-block;
  padding: 5px;
  background-color: blue;
  color: white;
  text-decoration: none;
  border-radius: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="map-nav">
  <a href="#" class="button prev-tab">Previous</a>
  <a href="#" class="button next-tab">Next</a>
</div>

<div class="map">
  <svg>
    <g data-dive="1" class="map-marker current">
      <circle cx="20" cy="25" r="20" fill="blue" />
      <text x="15" y="30" fill="white">1</text>
    </g>
    <g data-dive="2" class="map-marker">
      <circle cx="70" cy="25" r="20" fill="blue" />
      <text x="65" y="30" fill="white">2</text>
    </g>
    <g data-dive="3" class="map-marker">
      <circle cx="120" cy="25" r="20" fill="blue" />
      <text x="115" y="30" fill="white">3</text>
    </g>
  </svg>
</div>

<div id="1" class="map-content">Content 1</div>
<div id="2" class="map-content">Content 2</div>
<div id="3" class="map-content">Content 3</div>

答案 1 :(得分:0)

如何将:eq选择器与jQuery的$.index()方法一起使用?不过,您需要向.map-content div中添加一个容器元素:

$(document).ready(function() {
  var length = $('.map-content').length; // number of elements

  $('.map-marker').click(function() {
    var index = $(this).index(); // click element's place
    // handle classes
    $('.map-marker,.map-content').removeClass('current');
    $('.map-content:eq(' + index + ')').addClass('current');
    $(this).addClass('current');
    // show/hide depending on index  
    if (index == 0) {
      $('.prev-tab').hide();
      $('.next-tab').show();
    } else if (index == (length - 1)) {
      $('.prev-tab').show();
      $('.next-tab').hide();
    } else {
      $('.prev-tab,.next-tab').show();
    }
  });

  $('.next-tab').click(function() {
    var currentIndex = $('.map-content.current').index(); // get index
    var nextIndex = currentIndex + 1; // add 1
    // manage classes
    $('.map-marker, .map-content').removeClass('current');
    $('.map-content:eq(' + nextIndex + '),.map-marker:eq(' + nextIndex + ')').addClass('current');
    // hide next if last
    if (nextIndex == (length - 1)) {
      $(this).hide();
      $('.prev-tab').show();
    }
  });

  $('.prev-tab').click(function() {
    var currentIndex = $('.map-content.current').index(); // get index
    var prev = currentIndex - 1; // add 1
    // manage classes
    $('.map-marker, .map-content').removeClass('current');
    $('.map-content:eq(' + prev + '),.map-marker:eq(' + prev + ')').addClass('current');
    // hide prev if first
    if (prev == 0) {
      $(this).hide();
      $('.next-tab').show();
    }
  });
});
.current {
  border: solid 1px red;
}

.map span {
  display: inline-block;
  width: 30px;
  height: 30px;
  color: white;
  background: blue;
}

.map-content-container {
  margin: 30px auto;
}

.prev-tab {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="map">
  <span class="map-marker current">1</span>
  <span class="map-marker">2</span>
  <span class="map-marker">3</span>
</div>

<div class="map-content-container">
  <div class="map-content current">Content 1</div>
  <div class="map-content">Content 2</div>
  <div class="map-content">Content 3</div>
</div>

<div class="prev-tab">Prev</div>
<div class="next-tab">Next</div>

index()将返回父div内的位置,这将为您提供足够的信息来切换类(并添加或减去1,因此您可以使用{{ 1}}伪类)。您还可以添加一个小的条件,以在计数的开始/结束时隐藏:eq()标签。

注释:
  -请记住.prev/-next是从零开始的
  -尝试在html元素中不使用仅数字ID