简体   繁体   中英

Javascript onClick timed events?

I have a question! Is it possible to do timed on click events? I am writing a motor control program using RPi and python. I need buttons to control motor speed. At the moment the buttons only set fixated speed on push and set 0 speed on release. Would it be possible to do so that on press the button executes one function, after 1 second of holding another function and 1 second after that even another function?

Here is my whole page code at the moment (disregard the comments)

<!-- import jquery for later use, google offers hosted version .. this is how you make comments in HTML btw =) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script type="text/javascript">

    // declaring global variables:
    _running = false;
    _loader = document.createElement('div');
    _urlForward = "/pirmyn";
    _urlStop        = "/stoti";
    _urlLeft        = "/kaire";
    _urlRight       = "/desine";
    _urlBack        = "/atgal";
    _urlFoto        = "/foto";      
    // local variables, that would only be available in this <script> tag and not outside would have var ... infront
    // ->
    //      _running = false; <- global, accessible from any <script> tag at any time
    //      var _running = false; <- local, same name as global var, will cause funny random effect since javascript is stupid :P
    //      var running = false; <- local, only accessible inside this <script> tag or functions defined inside this tag


    // function to send a movement signal, will send the signal and also set _running to true so we know the motors are moving and we should send stop next time its called
    function sendMoveSignal(signal) {

        $(_loader).load(signal);
        _running = true;
    }

    // sends a function signal, motors wont be moving so we dont set _running to true
    function sendSignal(signal) {

        $(_loader).load(signal);
    }

    // takes the variable bId (button Id), grabs the element with that ID from HTML and sets its background colour to the active one
    function activateButton(bId) {

        var b = document.getElementById(bId);
        b.style.backgroundColor = "green";
    }

    // if motors are doing something (_running == true) we send stop and set _running to false so we know motors have stopped
    function sendStop() {

        if(_running)
        {
            $(_loader).load(_urlStop);
            _running = false;
        }               
    };

    // send forward signal to server and activate the forward button
    function onForward() {

        sendMoveSignal(_urlForward);                
        activateButton('bForward');
    };

    // send left signal to server and activate the left button
    function onLeft() {

        sendMoveSignal(_urlLeft);               
        activateButton('bLeft');
    };

    // .. as the ones above ;)
    function onRight() {

        sendMoveSignal(_urlRight);              
        activateButton('bRight');
    };

    function onBack() {

        sendMoveSignal(_urlBack);               
        activateButton('bBack');
    };

    function onFoto() {

        sendSignal(_urlFoto);
        activateButton('bFoto');
    };

    // call sendStop, it will only do something if motors are running (_running == true), after that deactivate all buttons
    function onStop() {

        sendStop();             
        deactivateAllButtons();
    };

    // graps each button object from HTML and sets the colour attribute to the inactive colour, could also set css class instead
    function deactivateAllButtons() {

        var startButton = document.getElementById('bForward');
        var leftButton  = document.getElementById('bLeft');
        var rightButton = document.getElementById('bRight');
        var backButton  = document.getElementById('bBack');
        var fotoButton  = document.getElementById('bFoto');

        startButton.style.backgroundColor = "red";
        leftButton.style.backgroundColor = "red";
        rightButton.style.backgroundColor = "red";
        backButton.style.backgroundColor = "red";
        fotoButton.style.backgroundColor = "red";
    }

    // this will be called from the browser once it has all files loaded completely, best entry point for any script since we can be sure that everything is loaded and ready here
    window.onload = function() {

        // call this to set all buttons to inactive by default when the page is loaded
        deactivateAllButtons();
    }
</script>

<!-- just thought it would be good to seperate controls and other functions here -->
<span id="controls" style="display:inline-block; border: 1px solid;">

    <div id="firstRow">
        <!-- onmousedown will fire when ANY mousebutton is clicked so rightclick works too here, if thats a problem it can be changed, just let me know =) -->
        <!-- onmouseup fires for any button too, we send stop there -->
        <!-- onmouseout fires when the mouse leaves the button area, we send stop to be sure .. onmouseup wont be triggered if the mouse is released outside of the context of the button -->
        <div id="bForward" onmousedown="onForward();" onmouseout="onStop();" onmouseup="onStop();" style="cursor:pointer;border:1px solid black;width:80px;margin:15px;margin-left:85px;padding:15px;text-align:center;">
            FORWARD
        </div>
    </div>

    <div id="secondRow">
        <span id="bLeft" onmousedown="onLeft();" onmouseout="onStop();" onmouseup="onStop();" style="display:inline-block;cursor:pointer;border:1px solid black;width:80px;margin:15px;padding:15px;text-align:center;">
            LEFT
        </span>

        <span id="bRight" onmousedown="onRight();" onmouseout="onStop();" onmouseup="onStop();" style="display:inline-block;cursor:pointer;border:1px solid black;width:80px;margin:15px;padding:15px;text-align:center;">
            RIGHT
        </span>
    </div>

    <div id="thirdRow">
        <div id="bBack" onmousedown="onBack();" onmouseout="onStop();" onmouseup="onStop();" style="cursor:pointer;border:1px solid black;width:80px;margin:15px;margin-left:85px;padding:15px;text-align:center;">
            BACK
        </div>
    </div>
</span>

<span id="functions" style="display:inline-block;position:absolute;">

    <!-- here onmouseout and onmouseup call deactivateAllButtons instead of onStop since we just want to make the foto button inactive again and not send any further signal -->
    <div id="bFoto" onmousedown="onFoto();" onmouseout="deactivateAllButtons();" onmouseup="deactivateAllButtons();" style="cursor:pointer;border:1px solid black;width:80px;margin:15px;margin-left:50px;padding:15px;text-align:center;">
        FOTO
    </div>

</span>

What you need to do is set handlers from script, not in html, and check time vs mouseup/mousedown, etc. for example

var sec = 1000;  //1 second in millisecs
var time;  //global for time checks

$(function() {  //set handlers after document loads
  var btn = $('#bBack');  //ex. button

  btn.mousedown(function(){
     immediateFunction(); //execute the 1st function
     time = (new Date()).getTime();
     btn.on('mouseup', foo);
     setTimeout(removeListener, sec); //remove listener after 1 second
  });

  function foo(){
       var timeNow = (new Date()).getTime();
       if(timeNow-time > sec){
         //now i know he released the button in more than 1 second, do X
       }else{
         //now i know he released the button in less than 1 second, do Y
       }
   }

   function removeListener(){
     btn.off('mouseup', foo); //remove listener
   }

   function immediateFunction(){
     console.log('whatever');
   }
});

also u could do this with promises, but it will be more complicated for somebody new in js, judging by in-html listeners and globals you use :) good luck

Yes it is. As you've already done, you can set a Date on mousedown and do stuff until mouseup, then do something more based on how long the button was held down for, hopefully the following is self explanatory.

Using an immediately invoked function expression (IIFE) means shared variables need not be global and keeps things compact.

 var foo = (function() { var timeStart; var elapsed = 0; var count = 0; var countElement; var timerRef; var msgEl; return { setStart: function() { timeStart = new Date(); foo.showCount(); msgEl = document.getElementById('finalMessage'); msgEl.textContent = ''; }, setEnd: function(callback) { if (timerRef) { clearTimeout(timerRef); timerRef = null; } document.getElementById('settingValue').textContent = count; // Do stuff with callback callback(); msgEl.textContent = 'All done'; }, showCount: function() { elapsed = new Date() - timeStart; count = elapsed / 100 | 0; document.getElementById('settingValue').textContent = count; timerRef = setTimeout(foo.showCount, 20); } }; }()); 
 <p>Setting is set to: <span id="settingValue">0</span></p> <button onmousedown="foo.setStart()" onmouseup="foo.setEnd(function(){console.log('End set')})">Set value</button> <p id="finalMessage"></p> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM