允许指针(单击)事件通过元素,同时保持滚动功能

时间:2017-01-11 13:33:30

标签: javascript html css dom

我的目标是拥有一个允许的元素:

  1. 下面的元素,点击/与之交互,
  2. 滚动
  3. 众所周知,1的解决方案是pointer-events: none。这与Click through a DIV to underlying elements中描述的一样。

    但是,无法滚动元素,因为滚动条显示在带有pointer-events: none的元素上。这可以在此示例中看到:http://jsbin.com/madure/2/edit?html,css,output

    是否有解决方法,或者是否需要在浏览器级别解决?也许还有一个额外的规则,pointer-events: scrollOnly

3 个答案:

答案 0 :(得分:1)

  

指针事件CSS属性指定在什么情况下(如果   任何)特定的图形元素可以成为鼠标的目标   的事件。

所以基本上如果你对上层不敏感进行点击,那么对于轮子事件也是如此。我建议两件事

JavaScript解决方法: 其中基本上使用的事实是:

  

请注意,阻止元素成为鼠标事件的目标   通过使用指针事件并不一定意味着鼠标事件   不能或不会触发该元素的听众



	$(function(){
		$("#stage-layer").on("wheel",function(e){
			eo=e.originalEvent;
			s=$("#scrollable")
			switch(eo.deltaMode){
				case 0: 		//DOM_DELTA_PIXEL		Chrome
					s.scrollTop(eo.deltaY+s.scrollTop())
					s.scrollLeft(eo.deltaX+s.scrollLeft())	
					break;
				case 1: 		//DOM_DELTA_LINE		Firefox
					s.scrollTop(15*eo.deltaY+s.scrollTop())	//scroll(e.deltaX, e.deltaY); 	Just a random small amount of scrolling 
					s.scrollLeft(15*eo.deltaX+s.scrollLeft())
					break;
				case 2: 		//DOM_DELTA_PAGE
					s.scrollTop(0.03*eo.deltaY+s.scrollTop())
					s.scrollLeft(0.03*eo.deltaX+s.scrollLeft())
					break;
			}
			e.stopPropagation();
			e.preventDefault()
		})
		
	})

.container {
    position: relative;
    width: 400px;
    height: 400px;
    border: 2px solid black;
}

#stage-layer {
    position: absolute;
    width: 100%;
    box-sizing: border-box;
    height: 100%;
    border: 2px solid yellow;
}

#application-layer {
    position: relative;
    box-sizing: border-box;
    height: 100%;
    border: 2px solid pink;
    pointer-events: none;
}

rect:hover {
    fill: blue;
}

#scrollable {
    overflow: auto;
    color: hotpink;
    height: 100px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    <div class="container">
        <svg id="stage-layer">
            <rect width="200" height="200"></rect>
        </svg>
        <div id="application-layer">
            <div id="scrollable">
                <p>foo1</p>
                <p>foo2</p>
                <p>foo3</p>
                <p>foo4</p>
                <p>foo5</p>
                <p>foo6</p>
            </div>
        </div>
    </div>
&#13;
&#13;
&#13;

一个不错的提示:

这可能不会立即产生解决方案,但它是长期网站开发的不错选择:

  

我们想要   在HTML中提供更细粒度的控制(而不仅仅是auto和none)...   如果您有任何您希望能做的特殊事情   有了这个属性,请将它们添加到用例部分   this wiki page(不要担心保持整洁)。

来源:pointer-events

答案 1 :(得分:1)

@ user10089632对香草javascript的回答

function scroller(event){
  scrollable=document.getElementById("scrollable");
  switch(event.deltaMode){
    case 0: 		//DOM_DELTA_PIXEL		Chrome
      scrollable.scrollTop+=event.deltaY
      scrollable.scrollLeft+=event.deltaX
      break;
    case 1: 		//DOM_DELTA_LINE		Firefox
      scrollable.scrollTop+=15*event.deltaY
      scrollable.scrollLeft+=15*event.deltaX
      break;
    case 2: 		//DOM_DELTA_PAGE
      scrollable.scrollTop+=0.03*event.deltaY
      scrollable.scrollLeft+=0.03*event.deltaX
      break;
  }
  event.stopPropagation();
  event.preventDefault()
}

document.onwheel = scroller;
.container {
    position: relative;
    width: 400px;
    height: 400px;
    border: 2px solid black;
}

#stage-layer {
    position: absolute;
    width: 100%;
    box-sizing: border-box;
    height: 100%;
    border: 2px solid yellow;
}

#application-layer {
    position: relative;
    box-sizing: border-box;
    height: 100%;
    border: 2px solid pink;
    pointer-events: none;
}

rect:hover {
    fill: blue;
}

#scrollable {
    overflow: auto;
    color: hotpink;
    height: 100px;
}
<div class="container">
    <svg id="stage-layer">
        <rect width="200" height="200"></rect>
    </svg>
    <div id="application-layer">
        <div id="scrollable">
            <p>foo1</p>
            <p>foo2</p>
            <p>foo3</p>
            <p>foo4</p>
            <p>foo5</p>
            <p>foo6</p>
        </div>
    </div>
</div>

答案 2 :(得分:-1)

它并没有真正“中断”滚动。如果您拥有pointer-events: none元素的元素子元素,那么实际上是继承了pointer-events: none CSS规则。

因此,如果您在子元素中设置pointer-events: all,则该子元素的所有设置都会恢复正常。父元素仍然允许指针事件通过,而子元素当然不会。我认为这是一种一致的行为。

修改后的JSBin: https://jsbin.com/dadixoyuqu/1/edit?html,css,output