Reputation: 14133
Is it possible to stop event propagation without preventing the default event behaviour?
This should let the input increment/decrement when scrolled but stop it from bubbling to any other elements and scrolling the outer div. (The following is Chrome-only, I think)
$("input[type=number]").on("mousewheel",function(e){ // only works with chrome I think
e.stopPropagation();
console.log("scrolled");
});
div{
height:50px;
overflow:auto;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div>
<input type='number'>
<div class='filler'></div>
</div>
But the stopPropagation
call seemingly does nothing. The outer div still scrolls.
Now, this particular issue (scrolling a number input) can be solved by preventingDefault
and manually incrementing and decrementing the input (JSFiddle).
I'm looking for a general solution that doesn't involve re-creating the default behaviour.
Upvotes: 0
Views: 619
Reputation: 214979
One possible workaround is to temporarily fix the input while mouse is over it:
$("input[type=number]").on("mousewheel",function(e){
e.stopPropagation();
}).on("mouseenter", function() {
$(this).css("position", "fixed");
}).on("mouseleave", function() {
$(this).css("position", "");
});
div{
height:50px;
overflow:auto;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div>
<input type='number'>
<div class='filler'></div>
</div>
Upvotes: 2
Reputation: 13304
So the preventDefault alternative is I my opinion the only one that will make this work.
I've thought of this alternative, but is basically the same. It sets the wheel event on the div and cancels it when the input is detected.
$("body > div").on("mousewheel",function(e){
if (e.target && e.target.tagName == "INPUT")
{
var currentVal = $(e.target).val() === "" ? 0:parseInt($(e.target).val(),10);
var step = $(e.target).attr("step") || 1;
//should have some min/max handling to be complete
if(e.originalEvent.wheelDelta > 0){
$(e.target).val(currentVal+parseInt(step,10));
}else{
$(e.target).val(currentVal-parseInt(step,10));
}
e.preventDefault();
}
});
http://jsfiddle.net/jgsp1ory/5/
Upvotes: 0