Filtre de gamme sur mesure en passant par défaut sur Blazor

voix
0

Im essayant de faire un filtre plage avec 2 gestionnaires et j'ai trouvé un fichier javascript et css pour cela, le problème est quand je lance le projet le filtre plage personnalisé apparaît et après 1 seconde passer par défaut. Vous pouvez voir ce problème dans ce référentiel GitHub en exécutant le projet et en accordant une attention dans le filtre de gamme et de rafraîchir la page.

Code HTML:

<input type=range multiple value=0,100 />

Code CSS:

@supports (--css: variables) {
    input[type=range].multirange {
        padding: 0;
        margin: 0;
        display: inline-block;
        vertical-align: top;
    }

        input[type=range].multirange.original {
            position: absolute;
        }

            input[type=range].multirange.original::-webkit-slider-thumb {
                position: relative;
                z-index: 2;
            }

            input[type=range].multirange.original::-moz-range-thumb {
                transform: scale(1); /* FF doesn't apply position it seems */
                z-index: 1;
            }

        input[type=range].multirange::-moz-range-track {
            border-color: transparent; /* needed to switch FF to styleable control */
        }

        input[type=range].multirange.ghost {
            position: relative;
            background: var(--track-background);
            --track-background: linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0 ) no-repeat 0 45% / 100% 40%;
            --range-color: hsl(190, 80%, 40%);
        }

            input[type=range].multirange.ghost::-webkit-slider-runnable-track {
                background: var(--track-background);
            }

            input[type=range].multirange.ghost::-moz-range-track {
                background: var(--track-background);
            }
}

Code Javascript:

(function () {
    use strict;

    var supportsMultiple = self.HTMLInputElement && valueLow in HTMLInputElement.prototype;

    var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, value);

    var multirange = function (input) {
        if (supportsMultiple || input.classList.contains(multirange)) {
            return;
        }

        var value = input.getAttribute(value);
        var values = value === null ? [] : value.split(,);
        var min = +(input.min || 0);
        var max = +(input.max || 100);
        var ghost = input.cloneNode();

        input.classList.add(multirange, original);
        ghost.classList.add(multirange, ghost);

        input.value = values[0] || min + (max - min) / 2;
        ghost.value = values[1] || min + (max - min) / 2;

        input.parentNode.insertBefore(ghost, input.nextSibling);

        Object.defineProperty(input, originalValue, descriptor.get ? descriptor : {
            // Fuck you Safari >:(
            get: function () { return this.value; },
            set: function (v) { this.value = v; }
        });

        Object.defineProperties(input, {
            valueLow: {
                get: function () { return Math.min(this.originalValue, ghost.value); },
                set: function (v) { this.originalValue = v; },
                enumerable: true
            },
            valueHigh: {
                get: function () { return Math.max(this.originalValue, ghost.value); },
                set: function (v) { ghost.value = v; },
                enumerable: true
            }
        });

        if (descriptor.get) {
            // Again, fuck you Safari
            Object.defineProperty(input, value, {
                get: function () { return this.valueLow + , + this.valueHigh; },
                set: function (v) {
                    var values = v.split(,);
                    this.valueLow = values[0];
                    this.valueHigh = values[1];
                    update();
                },
                enumerable: true
            });
        }

        if (typeof input.oninput === function) {
            ghost.oninput = input.oninput.bind(input);
        }

        function update() {
            ghost.style.setProperty(--low, 100 * ((input.valueLow - min) / (max - min)) + 1 + %);
            ghost.style.setProperty(--high, 100 * ((input.valueHigh - min) / (max - min)) - 1 + %);
        }

        ghost.addEventListener(mousedown, function passClick(evt) {
            // Are the ghost and input elements inverted? (ghost is lower range)
            var isInverted = input.valueLow == ghost.value;
            // Find the horizontal position that was clicked (as a percentage of the element's width)
            var clickPoint = evt.offsetX / this.offsetWidth;
            // Map the percentage to a value in the range (note, assumes a min value of 0)
            var clickValue = max * clickPoint;

            // Get the distance to both high and low values in the range
            var highDiff = input.valueHigh - clickValue;
            var lowDiff = Math.abs(input.valueLow - clickValue);

            if (isInverted ? highDiff < lowDiff : lowDiff < highDiff) {
                // The low value is closer to the click point than the high value
                // We should update the low value input
                var passEvent = new MouseEvent(mousedown, evt);
                // Pass a new event to the low input element (which is obscured by the
                // higher ghost element, and doesn't get mouse events outside the drag handle
                input.dispatchEvent(passEvent);
                // The higher ghost element should not respond to this event
                evt.preventDefault();
                return false;
            }
        });
        input.addEventListener(input, update);
        ghost.addEventListener(input, update);

        update();
    }

    multirange.init = function () {
        [].slice.call(document.querySelectorAll(input[type=range][multiple]:not(.multirange))).forEach(multirange);
    }

    if (typeof module === undefined) {
        self.multirange = multirange;
        if (document.readyState == loading) {
            document.addEventListener(DOMContentLoaded, multirange.init);
        }
        else {
            multirange.init();
        }
    } else {
        module.exports = multirange;
    }

})();

Merci de votre attention.

Créé 24/10/2019 à 12:01
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
0

Je pris le CSS fourni et appliqué à Blazor sans JavaScript.

Voici une preuve de concept (nécessite plus de travail sur le CSS - surtout se concentrer autour des contours) que vous pouvez prendre comme base.

Il est légèrement différent de la version JS fournie comme je ne l'ai pas comme la manipulation MouseDown - il se sentait aki.

Utilisez ce contrôle de l'échantillon comme celui-ci:

<RangeControl @bind-ValueHigh="ValueHigh" @bind-ValueLow="ValueLow"></RangeControl>
<span>@ValueLow</span>-<span>@ValueHigh</span>

@code {
    int ValueHigh=75;
    int ValueLow=25;
}

Créez un fichier RangeControl.razor et mettre cela en it: Le balisage / CSS / code sont tous dans un seul fichier pour le plaisir de le rendre facile à poster ici, dans la vraie vie, vous voudrez peut-être séparer une partie de cette (ou vous pourriez pas - avec Blazor c'est votre choix)

<div id="rc-@ID">
@(new MarkupString($@"<style>
        #rc-{ID} {{
            position: relative;
            width: {Width}px;
        }}

        #rc-{ID} > input[type='range'] {{            
            padding: 0;
            margin: 0;
            display: inline-block;
            vertical-align: top;
            width: 100%;
            --range-color: hsl(190, 80%, 40%);
            background: var(--track-background);
        }}
        #rc-{ID} > input[type='range']::-moz-range-track {{
            border-color: transparent; /* needed to switch FF to 'styleable' control */
        }}
        #rc-{ID} > input[name='low-range'] {{
            position: absolute;
            --track-background: linear-gradient(to right, transparent {100 * (ValueLow - MinValue) / (MaxValue - MinValue) + 1}%, var(--range-color) 0, var(--range-color) {100 * (ValueHigh - MinValue) / (MaxValue - MinValue) - 1}%, transparent 0 ) no-repeat 0 45% / 100% 40%;
        }}
        #rc-{ID} > input[name='low-range']::-webkit-slider-thumb {{
            position: relative;
            z-index: 2;
        }}
        #rc-{ID} > input[name='low-range']::-moz-range-thumb {{
                transform: scale(1); /* FF doesn't apply position it seems */
                z-index: 1;
            }}
        #rc-{ID} > input[name='high-range'] {{
            position: relative;
            --track-background: linear-gradient(to right, transparent {100 * (ValueLow - MinValue) / (MaxValue - MinValue) + 1}%, var(--range-color) 0, var(--range-color) {100 * (ValueHigh - MinValue) / (MaxValue - MinValue) - 1}%, transparent 0 ) no-repeat 0 45% / 100% 40%;
            clip-path: polygon({50 * (ValueLow + ValueHigh) / (MaxValue - MinValue) + 1}% 0, 100% 0, 100% 100%, {50 * (ValueLow + ValueHigh) / (MaxValue - MinValue) + 1}% 100%);
        }}

        #rc-{ID} > input[type='range']::-webkit-slider-runnable-track {{
            background: var(--track-background);
        }}

        #rc-{ID} > input[type='range']::-moz-range-track {{
            background: var(--track-background);
        }}
    </style>"))
    <input name="low-range" type="range" min="@MinValue" max="@MaxValue" @bind="@ValueLow" @bind:event="oninput" />
    <input name="high-range" type="range" min="@MinValue" max="@MaxValue" @bind="@ValueHigh" @bind:event="oninput" />
</div>
@code
{
    int _valueLow = 0;
    int _valueHigh = 100;
    [Parameter] public int Width { get; set; } = 200;
    [Parameter] public int MinValue { get; set; } = 0;
    [Parameter] public int MaxValue { get; set; } = 100;
    [Parameter] public int ValueLow {
        get => Math.Min(_valueLow,_valueHigh);
        set {
            if (_valueLow.Equals(value))
                return;
            _valueLow = value;
            if (_valueLow >= _valueHigh)
            {
                _valueLow = _valueHigh;
                _valueHigh = value;
                ValueHighChanged.InvokeAsync(_valueHigh);
            }
            ValueLowChanged.InvokeAsync(_valueLow);
        }
    }
    [Parameter] public int ValueHigh {
        get => Math.Max(_valueLow,_valueHigh);
        set {
            if (_valueHigh.Equals(value))
                return;
            _valueHigh = value;
            if (_valueLow >= _valueHigh)
            {
                _valueHigh = _valueLow;
                _valueLow = value;
                ValueLowChanged.InvokeAsync(_valueLow);
            }
            ValueHighChanged.InvokeAsync(_valueHigh);
        }
    }
    [Parameter] public EventCallback<int> ValueLowChanged { get; set; }
    [Parameter] public EventCallback<int> ValueHighChanged { get; set; }
    string ID = Guid.NewGuid().ToString().Replace("-", "").Substring(15);
}
Créé 24/10/2019 à 17:34
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more