简体   繁体   中英

Step by step execution of javascript or Jquery in specific condition

We have a task to append the given svg in a DIV and convert into inline svg when a button click (.button-new) .

So we have a div (#main-div) with specific width and height , for example width and height is 200 px.

And we have an svg with width and height is 50 px . So there are total_no_blocks =4 elements which fir into the container.

and we write the following code append the div with svg images.

for(var i =0;i<total_no_blocks;i++){
   $("#main-div").append("<img id=\"facebook-logo\" class=\"svg\"  src=\""+img_src+"\" width=\"100\" />");
}

and convert to inline svg we are using the following code

https://gist.github.com/Bloggerschmidt/61beeca2cce94a70c9df

jQuery('img.svg').each(function(){
    var $img = jQuery(this);
    var imgID = $img.attr('id');
    var imgClass = $img.attr('class');
    var imgURL = $img.attr('src');

    jQuery.get(imgURL, function(data) {
        // Get the SVG tag, ignore the rest
        var $svg = jQuery(data).find('svg');

        // Add replaced image's ID to the new SVG
        if(typeof imgID !== 'undefined') {
            $svg = $svg.attr('id', imgID);
        }
        // Add replaced image's classes to the new SVG
        if(typeof imgClass !== 'undefined') {
            $svg = $svg.attr('class', imgClass+' replaced-svg');
        }

        // Remove any invalid XML tags as per http://validator.w3.org
        $svg = $svg.removeAttr('xmlns:a');

        // Replace image with new SVG
        $img.replaceWith($svg);

    }, 'xml');

});

The problem is javascript not working step by step .

As per our code first 4 image need to append in div , second it converted to inline svg .

But what happens is that some time before load and show 4 image to main-div, it starts converting to inline svg . As the result in first time only 2 image loaded same time 3 image loaded or some time it is correct.

So the total code is like this [This is not complete code ]

$(".button-new").on("click",function(){
    $("#main-div").children().remove();

    for(var i =0;i<total_no_blocks;i++){

        $("#main-div").append("<img id=\"facebook-logo\" class=\"svg\"  src=\""+img_src+"\" width=\"100\" />");

    }



    jQuery('img.svg').each(function(){
        var $img = jQuery(this);
        var imgID = $img.attr('id');
        var imgClass = $img.attr('class');
        var imgURL = $img.attr('src');

        jQuery.get(imgURL, function(data) {
            // Get the SVG tag, ignore the rest
            var $svg = jQuery(data).find('svg');

            // Add replaced image's ID to the new SVG
            if(typeof imgID !== 'undefined') {
                $svg = $svg.attr('id', imgID);
            }
            // Add replaced image's classes to the new SVG
            if(typeof imgClass !== 'undefined') {
                $svg = $svg.attr('class', imgClass+' replaced-svg');
            }

            // Remove any invalid XML tags as per http://validator.w3.org
            $svg = $svg.removeAttr('xmlns:a');

            // Replace image with new SVG
            $img.replaceWith($svg);

        }, 'xml');

    });


     function 3() etc.......

});

I know javascript is synchronus but some cases like ajax it will work step by step , because it is waiting for the return message

.

How we can control the execution of script in current situation ?

What steps need to ensure that , all are executing step by step & all execution is properly finished ?

Let's sum up the scenario:

  • User clicks on .button-new button
  • element #main-div will be appended with total_no_blocks number of facebook logos, being img.svg
  • The img.svg items are iterated
  • An AJAX request is sent to the server to get the picture (in each iteration)
  • The response is interpreted as an SVG and written instead of the tag having an id

The main problem is that your code assumes that the facebook logos are being waited for. This is not how it works. In fact, the tags are created instantly and the iteration which follows occurs after the creation of the tags, BUT these are images which are loaded from somewhere (unless cached) and that's asynchronous. You need to implement a $("#main-div > img").load() handler and put your logic which replaces the image there. This will wait for the specific tag to be loaded and do what needs to be done. However, you have other problems as well. Your id is facebook-logo in each case, which defeats the purpose of id s, which is, to identify the tag. So you need this change as well into your cycle:

$("#main-div").append("<img id=\"facebook-logo" + i + "\" class=\"svg\"  src=\""+img_src+"\" width=\"100\" />");

which will make the items unique. Lastly, I do not understand why do you generate images which will have no purpose whatsoever and will consequently be overriden by svg images. If this has educational or illustrative purpose, then you might want to consider wrapping your $("#main-div > img").load() handler into a setTimeout , waiting for a second, for example to allow the human eyes to see what was the initial image. If not, then you could simply use svg from the start to avoid all the hassle.

Here is a small example where you can see what happens. Put a simple callback as parameter to your function.

  <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SVG 001</title> <style> body{font-family:"Calibri", sans-serif;} svg{border:1px solid #eee;float:left;} </style> </head> <body> <h1>Offset Dasharray</h1> <svg width="200" height="200" viewBox="0 0 500 500"> <path id="myPath" d="M 50 50 q 200 800 400 0" stroke="none"stroke-width="5" fill="none" /> </svg> <p id="astart"><p> <p id="aend"><p> <p id="acallback"><p> <script> var paintPathAni=function(path, duration, color, callback){ easeInOutQuad= function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t } var len=path.getTotalLength(); var aktLen; var sumSteps = duration / (1000/60) // 60 pics per second var step=1; var pathAnim; var anim=function(){ aktLen = easeInOutQuad(step/sumSteps)*len; path.setAttribute('stroke-dasharray', aktLen + ' ' + (len - aktLen)); path.setAttribute('stroke',color); if (step < sumSteps){ step++; pathAnim = setTimeout(anim, 1000/60) //1000/60 pics/second } else { clearTimeout(pathAnim); path.setAttribute('stroke',"red"); path.setAttribute('stroke-dasharray','none'); if (callback) return callback(); } } anim(); } astart.innerHTML="before function call"; paintPathAni(myPath, 5000,'red',function(){acallback.innerHTML="callback call";}); aend.innerHTML="after function call"; </script> </body> </html> 

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