在JavaScript中,我可以防止触发onmouseup事件,用我自己的事件代替吗?

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

我正在创建一个滑块小部件来管理值的范围,并完成其中的大部分。

这是一个演示:https://jsfiddle.net/d1wqb63a/

我想将其设置为在释放鼠标时实际触发 onmouseup 事件,其中包含其他数据。这是有效的,只是它现在触发了两次 onmouseup。一次直接通过浏览器,一次通过我的代码。

您可以在上面的 jsfiddle 演示中看到这一点。当正常事件调用时,控制台的输出是“未定义的”,而当我调用时,控制台输出一些实际数据,因为它正在尝试访问我添加的自定义信息。

这是我触发事件的方法:

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

我不知道如何禁用已经触发的事件;即,尽管我添加了 onmouseup 回调,但阻止浏览器触发实际的 onmouseup 事件。这甚至可行吗?

无论您在何处拦截本机鼠标弹起事件,您都可以接受原始事件作为处理程序的参数,然后调用 originalEvent.preventDefault()-- and possibly originalEvent.stopPropagation()preventDefault() 将阻止执行原始事件的正常操作,stopPropagation() 将阻止向上或向下冒泡到任何其他处理程序。

whateverElement.onmouseup = function (originalEvent) {
    originalEvent.preventDefault();
    originalEvent.stopPropagation();
    // create and dispatch your custom event here
}

Alexander上面的回答一般来说是最好的。

虽然看了你的代码,我认为有一个更精确的解决方案。

解决方案

尝试将您想要的值保存到滑块元素中。 然后将 mouseup 函数附加到 sildebar 元素本身而不是文档。无需激活新事件,如下所示:

// 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));
}

你的工作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>
注意:此 fiddle 记录 [对象对象],因为它不支持 JSON。我把它复制到你的 fiddle 并且它工作正常。