2

So I have a container with a grid of items and I want to be able to detect hover between rows. Not the individual items.

Hover areas

Its important to remember that the number of items, in the container and per row, will change.

My container of items currently looks like this

<div class="container">
    <div class="hover-placeholder"></div>
    <div class="row">
        <!-- Start : Items -->
            <div class="col-md-3">...</div>
            <div class="col-md-3">...</div>
            <div class="col-md-3">...</div>
            <div class="col-md-3">...</div>
            ...
            <div class="col-md-3">...</div>
        <!-- End : Items -->
    </div>
</div>

Preferably I DO NOT want to put a placeholder element every 4th item. Mainly because on smaller screens the number of items per row will reduce. This is why in my example above I have a single placeholder outside the grid that I want to transform: translateY(..) to the position between the hovered rows.

This is what I have currently: https://jsfiddle.net/0t8c0h4m/

Its nowhere near the result I am after but I have got to the point where I am overthinking it and getting stuck.

Any help would be great!


UPDATE

The goal for this functionality is when the user hovers the negative space, the .hover-placeholder will translate to that position and become visible. And when clicked will add a permanent separator between the rows.


SUCCESS!

I have solved my issue! Thank you all for your help.

Here is my solution: https://jsfiddle.net/0t8c0h4m/9/

Levi Cole
  • 3,561
  • 1
  • 21
  • 36
  • I'm interested in why you want to detect hover between elements. There is basically nothing the user can do, since there is literally nothing, so why would you want to hover there, except for not triggering any actions or resting your cursor? – AlexG Jun 02 '17 at 08:47
  • @AlexG please see my update in the question as to why I require this functionality. Thanks – Levi Cole Jun 02 '17 at 09:19

3 Answers3

1

I think that you are complicating stuff too much if you are only looking for the hover effect between the elements and nothing else.

Updated:

var offsets;

function get_offsets() {
  offsets = {};
  $('.card').each(function() {
    var $this = $(this);
    var card_offset = $this.offset().top;
    offsets[card_offset] = {
      ele: $this
    };
  })
}
get_offsets();

function get_last_ele(mouse_location) {
  var element;
  var previous_key;
  $.each(offsets, function(key, obj) {
    if (key > mouse_location && previous_key > 0) {
      element = offsets[previous_key].ele;
      return false;
    }
    previous_key = key;
  })
  return element;
}

$('.container').mousemove(function(e) {
  if ($(e.target).parents('.row').length == 0) {
    var last_item_row = get_last_ele(e.pageY)
    console.log(last_item_row.text())
  }
});

JSFiddle: https://jsfiddle.net/0t8c0h4m/6/

I'm only providing the code that gets the last item on the row before the space you are hovering. From there you can append the line or transition the placeholder the way you like it.

drip
  • 12,378
  • 2
  • 30
  • 49
  • Please see my update in the question as to why I require this functionality. Thanks – Levi Cole Jun 02 '17 at 09:20
  • @Levi Cole this changed the request from "just" a hover a lot. :) I updated the code to pull the last item on the row before where you are hovering. ( there is a console showing which element is taken ) From there it's your job to apply the transition and append the line after the item, so that you can have a little fun as well. – drip Jun 02 '17 at 10:34
0

Please try with following script

(function($) {
    'use strict';

  // Count items per row
  function items_per_row($collection) {
    var count = 0;

    $collection.each(function() {
      var $this = $(this);

      if ($this.prev().length > 0) {
        if ($this.position().top !== $this.prev().position().top) {
          return false;
        } else {
          count++;
        }
      } else {
        count++;
      }
    });

    var last = count ? $collection.length % count : 0,
        rows = count ? Math.round($collection.length / count) : 0;
    if (last == 0) {
      last = count;
    }

    return {
      count: count,
      last: last,
      rows: rows
    }
  };

  // On card hover, print current row
  $('.card').mouseenter(function() {
    var $card       = $(this);

    var item_count  = items_per_row( $('.card') ),
        index       = $(this).index(),
        current_row = Math.floor(index / item_count.count) + 1;

        $('pre').text( $card.find('.inner').text() + ' is in row '+ current_row );
  });
   $('.card').mouseout(function(){
  $('pre').text('');

  });


})(jQuery);
0

So I have come up with a solution to show dividers between each row using CSS. I just have been overthinking this issue.

I have added a dividing element after each item and with css nth-child() I can show specific dividers at each break point.

I have also added the grouping functionality I was aiming for.

Updated example: https://jsfiddle.net/0t8c0h4m/9/

Levi Cole
  • 3,561
  • 1
  • 21
  • 36