0

I have a problem, I think it's quite common on javacript but can't figure what to search.

JSfeedle equivalent: https://jsfiddle.net/Draykoon/55jzr2uq/19/ feedle with solution thanks @Joe https://jsfiddle.net/Draykoon/55jzr2uq/20/

I want to change the color of an arrow when onclick, then execute some code and set the color back to the original one.

I use sleep as an example but it's a function wich takes time but don't know how many. consider this code:

function sleep(seconds) 
{
    var e = new Date().getTime() + (seconds * 1000);
    while (new Date().getTime() <= e) {}
}

$('i.fa-chevron-circle-left').click(function(){
    var id = $(this).attr("id");
        $($("div.tab-pane")[id]).find("i.fa-chevron-circle-left").css("color","#ff9900");
        sleep(1);
        $($("div.tab-pane")[id]).find("i.fa-chevron-circle-left").css("color","#8BBE22");
});

the #ff9900 color is not showing on screen, it's like this line of code is skipped and worse when i don't reset the color to #8BBE22, the change only appears after the call to "sleep(1)", i want the user to be notified.

$('i.fa-chevron-circle-left').click(function(){
        var id = $(this).attr("id");
            $($("div.tab-pane")[id]).find("i.fa-chevron-circle-left").css("color","#ff9900");
            sleep(1);
            //color showing after 1 sec
    });

I know the $($("div.tab-pane")[id]).find("i.fa-chevron-circle-left") is not proper, I try $("div.tab-pane:nth-child(" +(id+1).toString() + ")" + " i.fa-chevron-circle-left" ) I got the same result, the color changed but with a delay.

I think i am missing an important behaviour of javascript.

Sleep should be replace with a call to an other function, i don't know the time of execution (redraw a graph in reality)

Thanks in advance.

Paltoquet
  • 1,184
  • 1
  • 10
  • 18
  • Can you post the HTML for `div.tab-pane`. It would be better with [**Stack Snippet**](https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/) or [**Fiddle**](http://jsfiddle.net/) – Pugazh Aug 25 '16 at 09:12
  • it's from a template and i use a library wich generate a svg, if i can figure it out withtout posting would be nice, sorry – Paltoquet Aug 25 '16 at 09:21
  • show us the redraw a graph code – Shiran Dror Aug 25 '16 at 10:13

3 Answers3

1

You can achieve it using setTimeout

Calls a function or executes a code snippet after a specified delay.

$('i.fa-chevron-circle-left').click(function(){
    var self = $(this);
    self.css("color","#ff9900");
    //Add your code, which you want to execute

    //Reset color after 1 second
    setTimeout(function(){
        self.css("color","#8BBE22");
    },  1000)
});
Satpal
  • 132,252
  • 13
  • 159
  • 168
  • Thanks, it looks like my problem exeept i don't know how much time my code will take to execute. I need to redrawn a graph and then at the end set the color back to the original one. I use sleep but in reality it's redraw – Paltoquet Aug 25 '16 at 09:19
  • I use webservice and ajax request to get some fresh data, won't work if we are not on the same domain. it's close to the sample just replace sleep with a function that takes time to execute. like @Joe said i think i need to run this method in a separate thread – Paltoquet Aug 25 '16 at 09:27
  • @DraykoonD, You can execute the code in the AJAX success callback method – Satpal Aug 25 '16 at 09:28
  • 1
    That could have done it but it's a bit more vicious, the ajax are just here to store data on buffer and then when the user want to see them i display them. I dont issue the request on the "onclick" method, i have them already – Paltoquet Aug 25 '16 at 09:32
0

This is because the script will run in it's entirety before the changes to the DOM are applied, as your script is synchronous. You basically need your code that sets the initial color to happen on a separate thread to the code that sets the second color, or else they will be applied at the same time.

To achieve this, as @Setpal has noted you can use setTimeout.

Update with code

Modified version of @Setpal's code

$('i.fa-chevron-circle-left').click(function(){
    var self = $(this);
    self.css("color","#ff9900");

    setTimeout(function(){
        //Add your code, which you want to execute
        self.css("color","#8BBE22");
    }, 0)
});
Joe
  • 1,847
  • 2
  • 17
  • 26
  • you are right, thanks is there a way to launch a function in a separate thread, without settimeout ? – Paltoquet Aug 25 '16 at 09:24
  • As noted in this answer - http://stackoverflow.com/questions/9516900/how-can-i-create-an-asynchronous-function-in-javascript setTimeout or setInterval are you only real options. You can just use setTimeout({ longFunction(); }, 0); which start your long running function immediately after your current call stack finishes. So in your case put everything following your initial color set into the timeout. – Joe Aug 25 '16 at 11:40
  • Thanks, it works perfectly. It's a bit akward but it did the job. – Paltoquet Aug 25 '16 at 11:49
  • That sums up JavaScript in general I think! – Joe Aug 25 '16 at 12:24
0

I would call a function and pass the id so it knows which arrow to change like so:

$('i.fa-chevron-circle-left').click(function(){
  var $this = $(this);
  var id = $this.attr("id");
  $this.css("color","#ff9900");
  myFunction(id);
});

myFunction(id) {
  // do something
  $("#" + id).css("color","#8BBE22");
}
Shiran Dror
  • 1,472
  • 1
  • 23
  • 36