Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow pointer (click) events to pass through element whilst maintaining scroll facility

My goal is to have an element which allows:

  1. elements underneath to be clicked on/interacted with,
  2. scrolling

The solution to 1 is widely known to be pointer-events: none. This is as described in Click through a DIV to underlying elements.

However, the element can not be scrolled, because the scroll bar appears on the element with pointer-events: none. This can be seen in this example: http://jsbin.com/madure/2/edit?html,css,output.

Is there a workaround to this, or is it something that would need to be addressed at the browser level? Perhaps with an additional rule, pointer-events: scrollOnly.

like image 661
Oliver Joseph Ash Avatar asked Jan 11 '17 13:01

Oliver Joseph Ash


People also ask

Does Safari support pointer events?

CSS pointer-events (for HTML) is Fully Supported on Safari 12, which means that any user who'd be accessing your page through Safari 12 can see it perfectly.

How do I make a div transparent to clicks?

Add CSS. You can solve this problem using the “none” value of the CSS pointer-events property. In the case of using this value, the element will not react to the pointer-events. With the help of the CSS background property put your transparent background.

How do you use pointer events?

The element can only be the target of a pointer event when the visibility property is set to visible and e.g. when a mouse cursor is over the interior (i.e., 'fill') of the element and the fill property is set to a value other than none , or when a mouse cursor is over the perimeter (i.e., 'stroke') of the element and ...

What is pointer events auto?

The pointer-events property allows for control over how HTML elements respond to mouse/touch events – including CSS hover/active states, click/tap events in Javascript, and whether or not the cursor is visible.


1 Answers

The pointer-events CSS property specifies under what circumstances (if any) a particular graphic element can become the target of mouse events.

So basically if you make the upper layer insensitive for click it will be so for wheel events too. I suggest on of two things

JavaScript workaround: Which basically use the fact that:

Note that preventing an element from being the target of mouse events by using pointer-events does not necessarily mean that mouse event listeners on that element cannot or will not be triggered

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

A nice tip:

This will not probably yield an immediate solution but it is a good choice for long term web development :

We would like to provide finer grained control (than just auto and none) in HTML ... if you have any particular things that you would like to be able to do with this property, then please add them to the Use Cases section of this wiki page (don't worry about keeping it tidy).

Source : pointer-events

like image 147
user10089632 Avatar answered Oct 04 '22 05:10

user10089632