jQuery open div on hover; automatic scroll through

2019-02-21 16:56发布

问题:

I have an UL list with several links in it, and each item is linked to its own DIV. When the user hovers over UL link, proper DIV box is shown.

Here is my HTML code:

<ul class="productlist">
  <li><a href="#" id="link0" class="product-link">Link 1</a></li>
  <li><a href="#" id="link2" class="product-link">Link 2</a></li>
  <li><a href="#" id="link3" class="product-link">Link 3</a></li>
</ul>

<div class="panel-overview boxlink" id="boxlink0"> Something goes here 1 </div>
<div class="panel-overview boxlink" id="boxlink1"> Something goes here 2 </div>
<div class="panel-overview boxlink" id="boxlink2"> Something goes here 3 </div>

and the JavaScript that makes it work (not a JavaScript expert, sorry):

<script>
$(function() {
    var $boxes = $('.boxlink');
    $('.productlist .product-link').mouseover(function() {
        $boxes.hide().filter('#box' + this.id).show();
    });    
});
</script>

I was wondering how can I make the boxes to be scrolled through automatically every 3 to 4 seconds. So for example, first DIV is opened for 3 seconds, then the second, then the third...

Here is the the live site, since I haven't really described it properly.

回答1:

Your description wasn't very clear to me, but this is how I interpereted it after viewing your website: Cycle through the links to show the nice images. This will happen automatically. BUT. If user wants to navigate, the cycle should stop

Here is the code for that.

$(document).ready(function () {
  var $boxes = $('.boxlink');
  var $links = $('.product-link');
  var cycle = false;
  var cycle_step = 0;

  $('.productlist .product-link').mouseenter(function() {
    boxActivate(this.id);
    stopCycle();
  });

  $('.productlist .product-link').mouseleave(function() {
    cycle = setTimeout(function(){
        startCycle();
    }, 1000);
  });

  var boxActivate = function(id){
    $boxes.hide().filter('#box' + id).show();
  }
  // cycle - only when mouse is not over links
  var startCycle = function(){
    cycle = setInterval(function(){
        boxActivate($links.get(cycle_step).id);
        cycle_step++;
        if(cycle_step==$links.length) {
            cycle_step=0;
        }
    }, 1000);
  }
  var stopCycle = function(){
    clearInterval(cycle);
  }

  startCycle();

});


回答2:

try it like this:

HTML:

<ul class="productlist">
  <li><a href="#" id="0" class="product-link">Link 1</a></li>
  <li><a href="#" id="1" class="product-link">Link 2</a></li>
  <li><a href="#" id="2" class="product-link">Link 3</a></li>
</ul>

<div class="panel-overview boxlink" id="boxlink0"> Something goes here 1 </div>
<div class="panel-overview boxlink" id="boxlink1"> Something goes here 2 </div>
<div class="panel-overview boxlink" id="boxlink2"> Something goes here 3 </div>

I changed the IDs of the <a>s.

JS

var current_box = 0; // Saves current shown box for timer
var timer_break = false; // Determines if timer shows boxes or not

// Function hides all boxes
function hide_boxes() {
    $('.boxlink').hide();
}

// Function shows box wit box_id and hides all other boxes
function show_box(box_id) { 
    hide_boxes();
    $('#boxlink'+box_id).show();
}

$(document).ready(function () {
    // Bind show_box to HOVER Event
    $('.product-link').mouseover(function () {
        timer_break = true;
        show_box($(this).attr('id'));
    });
    // Bind hide_box to MOUSEOUT Event
    $('.product-link').mouseout(function () {
        timer_break = false;
        hide_boxes();
        show_box(current_id); // So there is no "gap" until the timer hits again
    });
    // Initiate Timer 
    var show_timer = setInterval(function () {
        if(!timer_break) {
            if(current_box < 2) {
                current_box++;
            } else {
                current_box = 0;
            }
            show_box(current_box);
        } 
    },3000);
    // Show first Box after loading
    show_box(current_box);
});

Working JS Fiddle: http://jsfiddle.net/8527K/



回答3:

my solution fiddle

<ul class="product-list">
  <li><a href="#">Link 1</a></li>
  <li><a href="#">Link 2</a></li>
  <li><a href="#">Link 3</a></li>
</ul>
<ul class="product-info">
  <li>info 1</li>
  <li>info 2</li>
  <li>info 3</li>
</ul>

jquery

var jq_info = $('.product-info li').hide();
var tm = null, 
    tm_index=0, 
    info_len = jq_info.length;

function show(index){
   clearTimeout(tm);

   if (index != undefined) tm_index = index;

   if (tm_index >= info_len) tm_index = 0;

   jq_info.hide().eq(tm_index).show();
   if (++tm_index >= info_len) tm_index=0;


   tm = setTimeout(show, 3000);   
}

$('.product-list a').mouseover(function(){
    show($(this).closest('li').index());
})

show(0);


回答4:

Here is yet another solution with some data-target attributes for pointing content to show/hide.

var $links = $('.product-link'), current_id = 0, timeout;
$links.mouseover(function(el) {
    var $this = $(this);       
    $this.addClass("hover")
    showLink($this);
    clearTimeout(timeout);
});  

$links.mouseleave(function(el) {
    var $this = $(this);
    $this.removeClass("hover");
    timeout = setTimeout(cycle, 1000);
});

function showLink($link){
    var currentLink = $($links[current_id]);
    $(currentLink.data("target")).hide();
    $($link.data("target")).show();
    current_id = $link.parent().index();
} 

function cycle(){
    if($links.filter(".hover").length == 0){
        var next_id = (current_id + 1) % $links.length;
        showLink($($links[next_id]));
        timeout = setTimeout(cycle, 1000); 
    }           
}
timeout = setTimeout(cycle, 1000);

And as usual - a Fiddle, note changes in html.

UPDATE: Your page has an error:

<a href="http://www.carelle-creations.mybigcommerce.com/steps/" id="link13" class="current_link">Steps</a>

doesnt have product-link class. Add that and my solution (and probably other's) will work normal.

UPDATE2:

You can replace

$(currentLink.data("target")).hide();
$($link.data("target")).show();

With

$("#box" + currentLink.attr("id")).hide();
$("#box" + $link.attr("id")).show();

And it will work without changing html. I've tested this on your actual page.