简体   繁体   English

在特定条件下逐步执行javascript或jQuery

[英]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) . 我们的任务是将给定的svg附加到DIV并在单击按钮(.button-new)时转换为嵌入式svg

So we have a div (#main-div) with specific width and height , for example width and height is 200 px. 因此,我们有一个具有特定宽度和高度的div (#main-div) ,例如width和height为200 px。

And we have an svg with width and height is 50 px . 并且我们有一个svg,其宽度和高度为50 px So there are total_no_blocks =4 elements which fir into the container. 因此,共有total_no_blocks =4元素进入了容器。

and we write the following code append the div with svg images. 然后我们编写以下代码,将div附加到svg图片中。

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 并转换为嵌入式svg,我们使用以下代码

https://gist.github.com/Bloggerschmidt/61beeca2cce94a70c9df 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 . 问题是javascript无法逐步运行。

As per our code first 4 image need to append in div , second it converted to inline svg . 根据我们的代码,前4个图像需要在div中追加,然后将其转换为内联svg。

But what happens is that some time before load and show 4 image to main-div, it starts converting to inline svg . 但是发生的是,在加载并显示4张图片到main-div之前的一段时间,它开始转换为嵌入式svg。 As the result in first time only 2 image loaded same time 3 image loaded or some time it is correct. 结果是第一次只加载了2张图像,而同时加载了3张图像,或者有时是正确的。

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 我知道javascript是syncnus,但某些情况(例如ajax)将逐步运行,因为它正在等待返回消息

.

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 用户点击.button-new按钮
  • element #main-div will be appended with total_no_blocks number of facebook logos, being img.svg 元素#main-div将附加total_no_blocks个Facebook徽标,即img.svg
  • The img.svg items are iterated img.svg项被迭代
  • An AJAX request is sent to the server to get the picture (in each iteration) AJAX请求发送到服务器以获取图片(在每次迭代中)
  • The response is interpreted as an SVG and written instead of the tag having an id 响应被解释为SVG并被写入,而不是带有id的标签

The main problem is that your code assumes that the facebook logos are being waited for. 主要问题是您的代码假定正在等待Facebook徽标。 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. 您需要实现$("#main-div > img").load()处理函数,并在其中放置替换图像的逻辑。 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. 在每种情况下,您的id都是facebook-logo ,这违背了id s的目的,即标识标签。 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. 最后,我不明白为什么您生成的图像将毫无用处,因此会被svg图像覆盖。 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. 如果这具有教育性或说明性目的,则您可能需要考虑将$("#main-div > img").load()处理函数包装到setTimeout ,等待一秒钟,例如让人眼看到最初的图像是什么。 If not, then you could simply use svg from the start to avoid all the hassle. 如果没有,那么您可以从一开始就简单地使用svg来避免所有麻烦。

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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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