2017-01-30 5 views
1

Ich arbeite an einem Stepper/Spinner, die eine Standard-HTML-Select-Liste in einen Spinner, wo Sie + drücken, um nach oben und - nach unten gehen. Haben sie arbeiten OK ...Wie man JQuery Stepper/Spinner-Taste schneller durch die Liste auf drücken drücken?

https://jsfiddle.net/5pmarmov/40/

Aber wenn Sie + oder - mit der Maus und halten Sie, ich möchte es schneller durch die Liste blättern, anstatt müssen tatsächlich einmal klicken für jede Schritt der Liste.

Ist das möglich? Wenn ja, könnte mir jemand in die richtige Richtung zeigen?

Macht zu diesem Punkt keine Rolle, aber nur ein FYI, dass ich möchte, dass es auch in iOS und Android funktioniert. Nicht sicher, ob das separat gemacht wird oder ob der gleiche Code für den Desktop übernommen wird und auch auf allen mobilen Geräten funktioniert (Ideales Szenario, offensichtlich haha).

-Code ... HTML

<select name='weight' id='weightpicker' class='hide-cat-input select-step' > 
         <option value=''>Choose Weight</option> 
         <option value='5'>0 lbs or less</option><option value='5.0625'>5 lbs, 1 oz.</option><option value='5.125'>5 lbs, 2 oz.</option><option value='5.1875'>5 lbs, 3 oz.</option><option value='5.25'>5 lbs, 4 oz.</option><option value='5.3125'>5 lbs, 5 oz.</option><option value='5.375'>5 lbs, 6 oz.</option><option value='5.4375'>5 lbs, 7 oz.</option><option value='5.5'>5 lbs, 8 oz.</option><option value='5.5625'>5 lbs, 9 oz.</option><option value='5.625'>5 lbs, 10 oz.</option><option value='5.6875'>5 lbs, 11 oz.</option><option value='5.75'>5 lbs, 12 oz.</option><option value='5.8125'>5 lbs, 13 oz.</option><option value='5.875'>5 lbs, 14 oz.</option><option value='5.9375'>5 lbs, 15 oz.</option><option value='6'>6 lbs, 0 oz.</option><option value='6.0625'>6 lbs, 1 oz.</option><option value='6.125'>6 lbs, 2 oz.</option><option value='6.1875'>6 lbs, 3 oz.</option><option value='6.25'>6 lbs, 4 oz.</option><option value='6.3125'>6 lbs, 5 oz.</option><option value='6.375'>6 lbs, 6 oz.</option><option value='6.4375'>6 lbs, 7 oz.</option><option value='6.5'>6 lbs, 8 oz.</option><option value='6.5625'>6 lbs, 9 oz.</option><option value='6.625'>6 lbs, 10 oz.</option><option value='6.6875'>6 lbs, 11 oz.</option><option value='6.75'>6 lbs, 12 oz.</option><option value='6.8125'>6 lbs, 13 oz.</option><option value='6.875'>6 lbs, 14 oz.</option><option value='6.9375'>6 lbs, 15 oz.</option><option value='7'>7 lbs, 0 oz.</option><option value='7.0625'>7 lbs, 1 oz.</option><option value='7.125'>7 lbs, 2 oz.</option><option value='7.1875'>7 lbs, 3 oz.</option><option value='7.25'>7 lbs, 4 oz.</option><option value='7.3125'>7 lbs, 5 oz.</option><option value='7.375'>7 lbs, 6 oz.</option><option value='7.4375'>7 lbs, 7 oz.</option><option value='7.5' selected='selected'>7 lbs, 8 oz.</option><option value='7.5625'>7 lbs, 9 oz.</option><option value='7.625'>7 lbs, 10 oz.</option><option value='7.6875'>7 lbs, 11 oz.</option><option value='7.75'>7 lbs, 12 oz.</option><option value='7.8125'>7 lbs, 13 oz.</option><option value='7.875'>7 lbs, 14 oz.</option><option value='7.9375'>7 lbs, 15 oz.</option><option value='8'>8 lbs, 0 oz.</option><option value='8.0625'>8 lbs, 1 oz.</option><option value='8.125'>8 lbs, 2 oz.</option><option value='8.1875'>8 lbs, 3 oz.</option><option value='8.25'>8 lbs, 4 oz.</option><option value='8.3125'>8 lbs, 5 oz.</option><option value='8.375'>8 lbs, 6 oz.</option><option value='8.4375'>8 lbs, 7 oz.</option><option value='8.5'>8 lbs, 8 oz.</option><option value='8.5625'>8 lbs, 9 oz.</option><option value='8.625'>8 lbs, 10 oz.</option><option value='8.6875'>8 lbs, 11 oz.</option><option value='8.75'>8 lbs, 12 oz.</option><option value='8.8125'>8 lbs, 13 oz.</option><option value='8.875'>8 lbs, 14 oz.</option><option value='8.9375'>8 lbs, 15 oz.</option><option value='9'>9 lbs, 0 oz.</option><option value='9.0625'>9 lbs, 1 oz.</option><option value='9.125'>9 lbs, 2 oz.</option><option value='9.1875'>9 lbs, 3 oz.</option><option value='9.25'>9 lbs, 4 oz.</option><option value='9.3125'>9 lbs, 5 oz.</option><option value='9.375'>9 lbs, 6 oz.</option><option value='9.4375'>9 lbs, 7 oz.</option><option value='9.5'>9 lbs, 8 oz.</option><option value='9.5625'>9 lbs, 9 oz.</option><option value='9.625'>9 lbs, 10 oz.</option><option value='9.6875'>9 lbs, 11 oz.</option><option value='9.75'>9 lbs, 12 oz.</option><option value='9.8125'>9 lbs, 13 oz.</option><option value='9.875'>9 lbs, 14 oz.</option><option value='9.9375'>9 lbs, 15 oz.</option><option value='10'>10 lbs, 0 oz.</option><option value='10.0625'>10 lbs, 1 oz.</option><option value='10.125'>10 lbs, 2 oz.</option><option value='10.1875'>10 lbs, 3 oz.</option><option value='10.25'>10 lbs, 4 oz.</option><option value='10.3125'>10 lbs, 5 oz.</option><option value='10.375'>10 lbs, 6 oz.</option><option value='10.4375'>10 lbs, 7 oz.</option><option value='10.5'>10 lbs, 8 oz.</option><option value='10.5625'>10 lbs, 9 oz.</option><option value='10.625'>10 lbs, 10 oz.</option><option value='10.6875'>10 lbs, 11 oz.</option><option value='10.75'>10 lbs, 12 oz.</option><option value='10.8125'>10 lbs, 13 oz.</option><option value='10.875'>10 lbs, 14 oz.</option><option value='10.9375'>10 lbs, 15 oz.</option><option value='11'>11 lbs, 0 oz.</option><option value='11.0625'>11 lbs, 1 oz.</option><option value='11.125'>11 lbs, 2 oz.</option><option value='11.1875'>11 lbs, 3 oz.</option><option value='11.25'>11 lbs, 4 oz.</option><option value='11.3125'>11 lbs, 5 oz.</option><option value='11.375'>11 lbs, 6 oz.</option><option value='11.4375'>11 lbs, 7 oz.</option><option value='11.5'>11 lbs, 8 oz.</option><option value='11.5625'>11 lbs, 9 oz.</option><option value='11.625'>11 lbs, 10 oz.</option><option value='11.6875'>11 lbs, 11 oz.</option><option value='11.75'>11 lbs, 12 oz.</option><option value='11.8125'>11 lbs, 13 oz.</option><option value='11.875'>11 lbs, 14 oz.</option><option value='11.9375'>11 lbs, 15 oz.</option><option value='12'>12 lbs or more</option> 
         </select> 

JS:

$(function() { 
    $(".select-step").selectStep({ 
      onChange: function(value) { 
      console.log(value, "value"); 
      } 
     }); 
    }) 
(function ($) { 
    $.fn.selectStep = function (vars) { 
     /* 
     * Function to get all plugin's variables 
     * and element options on array 
     */ 
     function getData(element, callback) { 
      // Define default variables 
      var defaultVars = { 
       onChange: null, 
       incrementLabel: "+", 
       decrementLabel: "-" 
      }; 
      var assign = Object.assign; 
      // Get all plugin variables 
      vars = assign({}, defaultVars, vars); 
      var options = []; 
      // Get select options 
      var optElement = $(element).find("option"); 
      optElement.each(function (i, o) { 
       var name = $(this).text(); 
       var value = $(this).attr("value"); 
       var selected = $(this).is(':selected'); 
       options = options.concat([{ name: name, value: value, selected: selected }]); 
       if (i === optElement.length - 1) { 
        // Fire callback with select options and variables 
        callback(vars, options); 
       } 
      }); 
     } 
     /* 
     * Function to create fake element 
     * to mock the select elements 
     */ 
     function addFakeElements(element, callback) { 
      getData(element, function (vars, options) { 
       // Check if options is empty 
       if (!options.length) { 
        return; 
       } 
       // Add class to select element 
       jQuery(element).addClass("select-step"); 
       // Add fake elements 
       var incrementLabel = vars.incrementLabel, decrementLabel = vars.decrementLabel; 
       // Find selected option on the select element 
       var isSelected = []; 
       options.map(function (opt, key) { 
        if (opt.selected) { 
         isSelected = isSelected.concat([{ key: key, name: opt.name, value: opt.value }]); 
        } 
        return false; 
       }); 
       var selectedOptionName = isSelected.length ? isSelected[0].name : null; 
       var selectedOptionKey = isSelected.length ? isSelected[0].key : null; 
       var selectedOptionvalue = isSelected.length ? isSelected[0].value : null; 
       // Create the fake element 
       var fakeElement = "<div class=\"jquery-select-step-element\">\n     <div class=\"decrementStep\">" + decrementLabel + "</div>\n     <div class=\"selectStepValue\" data-key=\"" + selectedOptionKey + "\" data-value=\"" + selectedOptionvalue + "\">\n     " + selectedOptionName + "\n     </div>\n     <div class=\"incrementStep\">" + incrementLabel + "</div>\n    </div>"; 
       // Wrap select to a div 
       var parentElement = $(element) 
        .wrap("<div class=\"jquery-select-step\"></div>") 
        .parent(); 
       // Append the fake element 
       parentElement.append(fakeElement); 
       // Fire callback when finished 
       callback(vars, options, parentElement); 
      }); 
     } 
     /* 
     * Function to check if variable is function 
     */ 
     function isFunction(functionToCheck) { 
      var getType = {}; 
      return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 
     } 
     /* 
     * Function to handle the increment and decrement of the plugins 
     * it fire onChange event and change the select value 
     */ 
     function handleChange(element, vars, options, type) { 
      var selectStepValue = $(element).find(".selectStepValue"); // Get the element that show the value 
      var key = parseInt($(selectStepValue).attr("data-key")); // Get current active key 
      var onChange = vars.onChange; // Get user onChange event 
      // Check if the key is not less than 0 or bigger than select options length 
      if (type === "decrement" && key <= 0 || type === "increment" && key >= options.length - 1) { 
       return; 
      } 
      // Get the new key 
      var newKey = (type === "decrement" ? (key - 1) : (key + 1)); 
      var _a = options[newKey], name = _a.name, value = _a.value; // Get name and value of the new key 
      // Change value 
      selectStepValue.text(name); 
      selectStepValue.attr("data-key", newKey); 
      selectStepValue.attr("data-value", value); 
      // Change select element selected options 
      jQuery(element).find(".select-step option").removeAttr('selected'); 
      jQuery(element).find(".select-step option:eq(" + newKey + ")").attr('selected', true); 
      // Fire onChange event 
      if (onChange !== null && isFunction(onChange)) { 
       onChange({ 
        key: newKey, 
        name: name, 
        value: value 
       }); 
      } 
     } 
     /* 
     * Function to initialize the plugins 
     */ 
     function init(element) { 
      addFakeElements(element, function (vars, options, parentElm) { 
       // Listen to change event 
       $(parentElm).on("click", ".decrementStep", function() { 
        handleChange(parentElm, vars, options, "decrement"); 
       }); 
       $(parentElm).on("click", ".incrementStep", function() { 
        handleChange(parentElm, vars, options, "increment"); 
       }); 
      }); 
     } 
     init(this); 
     return this; 
    }; 
}(jQuery)); 

CSS:

/* Do not change */ 

.select-step { 
    width: 0.1px; 
    height: 0.1px; 
    opacity: 0; 
    overflow: hidden; 
    position: absolute; 
    z-index: -1; 
    -webkit-appearance: none; 
} 

/* You can change from here */ 

.jquery-select-step { 
    display: inline-block; 
} 
.jquery-select-step-element { 
    position: relative; 
    display: inline-block; 
    padding: 5px 45px; 
    font-size: 13px; 
    font-weight: bold; 
    line-height: 20px; 
    color: #333; 
    white-space: nowrap; 
    vertical-align: middle; 
    user-select: none; 
    background-color: #fff; 
    border: 1px solid #d5d5d5; 
    border-radius: 3px; 
} 
.jquery-select-step-element > div { 
    display: inline-block; 
} 
.decrementStep, .incrementStep { 
    position: absolute; 
    width: 30px; 
    left: 0; 
    top: 0; 
    padding: 5px; 
    text-align: center; 
    border-right: 1px solid #d5d5d5; 
    background-image: -webkit-linear-gradient(#fcfcfc, #eee); 
    background-image: linear-gradient(#fcfcfc, #eee); 
    cursor: pointer; 
} 
.incrementStep { 
    left: auto; 
    right: 0; 
    border-right: 0; 
    border-left: 1px solid #d5d5d5; 
} 

Antwort

3

Mit einer Kombination aus setTimeout und setInterval Variablen zugewiesen mit mousedown und mouseup Ereignis Listener können Sie einen Frequenzzähler nach einer festgelegten Zeit von mousedown starten und dann diese Timer auf mouseup löschen.

Wenn Sie die letzte Funktion in Ihrem js mit diesem ersetzen (aus Zeile 114). Sie können die Aktionen in Funktionen abkürzen, um sie ein wenig TROCKENER zu machen, sie bleiben hier offen für Erklärungen.

Für Android und IOS sind die Ereignislistener touchstart bzw. touchend. hier

Geige: https://jsfiddle.net/manoeuvres/hmjc949t/1/

/* 
* Function to initialize the plugins 
*/ 
var timer1, freq1; 

function init(element) { 
    addFakeElements(element, function (vars, options, parentElm) { 
     // Listen to change event 
     $(parentElm).on({ 
      click: function() { 
       handleChange(parentElm, vars, options, "increment"); 
      }, 
      'touchstart mousedown': function(){ 
      timer1 = setTimeout(function(){ 
       freq1 = setInterval(function(){ 
       handleChange(parentElm, vars, options, "increment"); 
       }, 300); // vary this to control speed 
      },300); // vary this to control start delay 
      }, 
      'touchend mouseup': function(){ 
      clearTimeout(timer1); 
      clearInterval(freq1); 
      } 
     },".incrementStep"); 
     $(parentElm).on({ 
      click: function() { 
       handleChange(parentElm, vars, options, "decrement"); 
      }, 
      'touchstart mousedown': function(){ 
      timer1 = setTimeout(function(){ 
       freq1 = setInterval(function(){ 
       handleChange(parentElm, vars, options, "decrement"); 
       }, 300); // vary this to control speed 
      },300); // vary this to control start delay 
      }, 
      'touchend mouseup': function(){ 
      clearTimeout(timer1); 
      clearInterval(freq1); 
      } 
     },".decrementStep"); 
    }); 
} 
+0

Funktioniert prima, danke! Nur neugierig, wenn Sie irgendwelche Gedanken dazu haben ... auf Handy (im Test auf dem iPhone in Safari), wenn Sie drücken und halten Sie das +, es durchläuft, wie es sollte, aber auch einige der "Gewicht" Text markiert (" oz. ", um genau zu sein) und öffnet die Kopier-/Einfügeoptionen, die in iOs sind. Dies wäre für den Benutzer ärgerlich, also wundern Sie sich, wenn Sie wissen, wie Sie das verhindern können? Oder ist das nur Standard-Browserverhalten, das nicht vermieden werden kann? – user3304303

+1

sicher kein Problem, einfach hinzufügen '.selectStepValue {user-select: none; } 'zu deinem CSS. Sollte den Trick machen. Alternativ kann eine "handcranked" Methode den Text mit einem transparenten div abdecken. – Sam0

+0

FYI, ich musste hinzufügen "-webkit-user-select: none! Wichtig;" auch, um es in iOS zu arbeiten, scheint aber jetzt gut zu sein. Vielen Dank! – user3304303

Verwandte Themen