DanielST
DanielST

Reputation: 14133

stopPropagation without preventing default

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

Answers (2)

georg
georg

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

Mouser
Mouser

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

Related Questions