当光标在右列上方时如何滚动左列?

Posted

技术标签:

【中文标题】当光标在右列上方时如何滚动左列?【英文标题】:How to scroll left column when cursor is above right column? 【发布时间】:2016-03-09 22:44:23 【问题描述】:

当我在地图画布上滚动时如何上下滚动左列?

地图已禁用滚轮传播,如果可能仅通过 CSS 完成它会很好。我尝试将 #map_canvas 包装为其他具有 flex 属性的 div 并将地图设置为绝对位置和 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>

【问题讨论】:

您仍然希望地图接收拖放、单击、双击事件,还是应该完全静态? 我只想取消缩放滚动事件,其他事件应该可用。 $("#map_canvas").scrollLeft(); 是一个吸气剂。它只是返回一个整数,也许你想让$("#map_canvas").scrollLeft(0) 一直滚动到左边?在这种情况下,即使这样也是错误的,因为您通过设置center 属性在谷歌地图中“滚动”。地球是一个球体,没有“起始”位置。 我的回答能解决你的问题吗? 好的,非常感谢!我只需要将其调整为响应式设计。 【参考方案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】:

这是一种通过javascript将容器#canvas_container的滚动事件转移到左列的方法。为此,地图必须位于容器内并在顶部和底部填充(.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 的唯一缺点是地图上可见的垂直滚动条。

要自己玩,请参阅this fiddle。

$(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>

【讨论】:

以上是关于当光标在右列上方时如何滚动左列?的主要内容,如果未能解决你的问题,请参考以下文章

当光标位于屏幕的顶部或底部边缘时,如何使用 JQuery/Javascript 向下滚动页面?

如何阻止固定元素阻止滚动页面?

滚动后如何确定光标在画布上的位置?

修复了引导列内的 div [关闭]

具有流体左列和固定右列的两列 div 布局

当用户将鼠标悬停在滑块上时,使光标成为手