Skip to content
Advertisement

In JavaScript, can I prevent the onmouseup event from being triggered, replacing it with my own event?

I’m creating a slider widget to let me manage ranges of values, and have most of it complete.

Here is a demo of it: https://jsfiddle.net/d1wqb63a/

I want to set it up to actually trigger an onmouseup event when the mouse is released, with additional data in it. That is working, except that it is now triggers the onmouseup twice. Once directly by the browser and once by my code.

You can see that in the jsfiddle demo above. The output to the console is “undefined” when called by the normal event, and some actual data when called by mine, as it’s trying to access the custom info I added.

Here’s what I’m doing to trigger the event:

var e = new Event('mouseup');
e.sliderValues = JSON.parse(JSON.stringify(config.values));
element.dispatchEvent(e);

What I don’t know is how to disable the already triggered event; i.e, stop the browser from triggering the actual onmouseup event despite my adding the onmouseup callback. Is that even doable?

Advertisement

Answer

Alexander‘s answer above is the best generally speaking.

Though looking at your code I think that there is a more precise solution for you.

Solution

Try saving the values you want into the slider element. Then appending your mouseup function to the sildebar element itself instead of the document. Without the need to active a new event, like so:

// save your config sidler values to the element:
// (inside your mousemove event)
element.dataset.sliderValues = JSON.parse(JSON.stringify(config.values));

// then at the end of the code call it like so:
let slideBar = document.getElementById('example');
slideBar.onmouseup = function(e){
    console.log(JSON.stringify(slideBar.dataset.sliderValues));
}

Your working fiddle:

function buildSlider(element, config){
        var boundingBox = element.getBoundingClientRect();
        var n;

        // let's make sure all of the necessary parameters are in place
        var defaults = {
                min : 0,
                max : 100,
                step : 0,
                values : {i : 0},
                reversible: false,
                bevel : true

        };
        if(config == undefined) config = {};
        for(n in defaults){
                if(config[n] == undefined){
                        config[n] = defaults[n];
                }
        }
        config.step = Math.abs(config.step); // <-- idiot proofing


        // now we can add style and events
        element.classList.add('slider');

        for(idx in config.values){
                var widget = document.createElement('div');
                element.appendChild(widget);

                // center it vertically
                var halfHeight = boundingBox.height / 2;
                widget.style.marginTop = -(widget.getBoundingClientRect().height / 2) + 'px';
                widget.style.top = halfHeight + 'px';

                // initialize each handle
                (function(component, idx){

                        // set the initial position
                        var xOffset = component.getBoundingClientRect().width >> 1;
                        component.style.left = (boundingBox.width * (config.values[idx] - config.min) / (config.max - config.min) - xOffset) + 'px';

                        // add events
                        component.onmousedown = function(){
                                document.onmousemove = function(e){
                                        var x, value;
                                        x = e.clientX - boundingBox.left;

                                        // make sure we're within the range of the widget
                                        x = x < 0 ? 0 : (x > boundingBox.width ? boundingBox.width : x);
                                        value = x / boundingBox.width * (config.max - config.min) + config.min;

                                        if(config.step > 0){
                                                // if we have a step value, snap to that
                                                value = Math.round(value / config.step) * config.step;
                                                x = boundingBox.width * (value - config.min) / (config.max - config.min);
                                        }

                                        config.values[idx] = value;
                                        component.style.left = (x - xOffset) + 'px';
//                                                      var e = new Event('change')
                                                                                
                                        // ### change 1 #####
                                                                                element.dataset.sliderValues = JSON.parse(JSON.stringify(config.values));
                                }
                                // ### document.onmouseup here was deleted
                        }
                })(widget, idx);

        }

}

window.onload = function(){
        buildSlider(document.getElementById('example'), {min: -50, max : 50, step : 5, values: {a : -25, b : 25}})
        // ### change 2 #####
        const sliderEl = document.getElementById('example')
        sliderEl.offsetWidth
        sliderEl.addEventListener('mouseup', function(){
                        document.onmousemove = null;
                console.log(JSON.stringify(sliderEl.dataset.sliderValues));
        })
};
.slider{
        border-radius: 1000cm; /* stupid css lacking an elegant way for dynamic circluar ends */
        position: relative;
        border: 1px solid;
        /*box-shadow: rgb(0 0 0 / 50%) -2px -2px 2px 2px inset, rgb(255 255 255 / 60%) 2px 2px 2px 2px inset;*/
}

.slider > div{
        border: inherit;
        display:inline-block;
        position: absolute;
        background-color: inherit;
        border-radius: inherit;
        box-shadow: inherit;
        height: 5mm;
        width: 5mm;

        /* make it unselectable */
        -moz-user-select: -moz-none;
        -khtml-user-select: none;
        -webkit-user-select: none;
        -o-user-select: none;
        user-select: none;
}
<body style="padding: 2em">
<div>
<div id="example" style="width: 10em; height: 1em; background-color:#FED; display: inline-block; margin-left:3cm"></div>
</div>
</body>
Note: this fiddle logs [object object] since it doesnt support JSON. I copied it to your fiddle and it works fine.
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement