Как прокручивать левый столбец, когда курсор находится выше правого столбца?

Как прокручивать вверх и вниз по левому столбцу при прокрутке над холстом карты?

Карта отключила распространение колесика прокрутки, было бы неплохо выполнить ее, если возможно, только с помощью CSS. Я попытался обернуть #map_canvas другим div с использованием свойства flex и установить карту в положение absolute и 100vh/vw, но это не влияет на круговое движение.

$(document).ready(function() {
  var post = "<h3>Post title</h3><div>Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</div><hr>";
  var i = 0;
  while (i < 10) { $('#left_container').append(post); i++; }

  var options = {
    zoom: 10,
    scrollwheel: false,
    center: new google.maps.LatLng(49, 17)
  };
  var map = new google.maps.Map($('#map_canvas')[0], options);

  $("#map_canvas").scrollLeft();
});
.flexbox-container {
  display: -ms-flex;
  display: -webkit-flex;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  height: 100vh;
}
.flexbox-container #left_container {
  flex: 1;
  padding: 0 5px;
  overflow-y: auto;
  height: 100vh;
}
#map_canvas {
  flex: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3&amp;sensor=false"></script>

<div class="flexbox-container">
  <div id="left_container"></div>
  <div id="map_canvas"></div>
</div>

Ответ 1

jsfiddle

В этом решении я предполагаю, что карта имеет ширину 200px. Вы можете заменить его на другое значение в css и js.

Вы хотите прокрутить крайний левый столбец, когда мышь наводит правый столбец (карту).
Для этого крайний левый столбец должен фактически занимать все область просмотра, хотя визуально это не выглядит.

В #left_container ниже вы можете видеть, что это абсолютно помещено, чтобы соответствовать всем родительским границам .flexbox-container. Тройной частью является border-right: 200px transparent solid, который "толкает" вертикальную полосу прокрутки влево.

Итак, когда вы перемещаете колесико мыши на карте, вы фактически наводите правую границу #left_container и тем самым перемещаете ее вверх и вниз, а не карту.

.flexbox-container {
  height: 90vh;
  position: relative;
}

#left_container {
  padding: 0 5px;
  overflow-y: auto;
  display: inline-block;
  height: 100%;
  border-right: 200px transparent solid;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  pointer-events: none;
}

#left_container.scrollMap {
  pointer-events: auto;
}

#map_canvas {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 200px;
}

Вышеупомянутое решение CSS полностью игнорирует другие события карт (dblclick, click,...)
Чтобы исправить это, нам нужно немного JS, чтобы игнорировать события мыши в крайнем левом столбце (см. pointer-events):

  var map_canvas = $('#map_canvas')[0],
      $left_container = $('#left_container'),
      $parent = $('.flexbox-container'),
      options = {
          zoom: 10,
          scrollwheel: false,
          center: new google.maps.LatLng(49, 17)
      },
      map = new google.maps.Map(map_canvas, options),
      wheelEvent = function (e) {
          $left_container.addClass('scrollMap');
      };

  map_canvas.addEventListener('mousewheel', wheelEvent);
  map_canvas.addEventListener('DOMMouseScroll', wheelEvent);
  $parent.mousemove(function (e) {
    if (e.clientX < $parent.width() - 200) {
      $left_container.addClass('scrollMap');
    } else {
      $left_container.removeClass('scrollMap');
    }    
  });


<div class="flexbox-container">
    <div id="left_container" class="scrollMap"></div>
    <div id="map_canvas"></div>
</div>

Ответ 2

Здесь можно передать событие прокрутки контейнера #canvas_container в левый столбец с помощью javascript. Для этого карта должна быть внутри контейнера и заполнена сверху и снизу (.padder).

Таким образом, вы можете теоретически прокручивать вверх и вниз, перехватывать это событие прокрутки и переносить его в левый столбец. Другие события не затрагиваются.

Ключевой частью является этот javascript:

  $canvas_container = $('#canvas_container')
  $left_container = $('#left_container');
  initial_offset = 100;

  $canvas_container.scrollTop(initial_offset);

  $canvas_container.on('scroll', function(e) {
    $left_container.scrollTop($left_container.scrollTop() + $canvas_container.scrollTop() - initial_offset);
    $canvas_container.scrollTop(initial_offset);
  });

Только недостаток я вижу, что atm - видимая вертикальная полоса прокрутки на карте.

Чтобы поиграть самостоятельно, см. эту скрипту.

$(document).ready(function() {
  var post = "<h3>Post title</h3><div>Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</div><hr>";
  var i = 0;
  while (i < 10) {
    $('#left_container').append(post);
    i++;
  }

  var options = {
    zoom: 10,
    scrollwheel: false,
    center: new google.maps.LatLng(49, 17)
  };
  var map = new google.maps.Map($('#map_canvas')[0], options);


  $canvas_container = $('#canvas_container')
  $left_container = $('#left_container');
  initial_offset = 100; // same as height of .padder

  $canvas_container.scrollTop(initial_offset);

  $canvas_container.on('scroll', function(e) {
    $left_container.scrollTop($left_container.scrollTop() + $canvas_container.scrollTop() - initial_offset);
    $canvas_container.scrollTop(initial_offset);
  });

});
.flexbox-container {
  display: -ms-flex;
  display: -webkit-flex;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  height: 80vh;
}
.flexbox-container #left_container {
  flex: 1;
  padding: 0 5px;
  overflow-y: auto;
  height: 80vh;
}
#canvas_container {
  flex: 2;
  height: 80vh;
  overflow-y: scroll;
}
#map_canvas {
  height: 100%;
}
.padder {
  height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3&amp;sensor=false"></script>

<div class="flexbox-container">
  <div id="left_container"></div>
  <div id="canvas_container">
    <div class="padder"></div>
    <div id="map_canvas"></div>
    <div class="padder"></div>
  </div>
</div>