由$(document).ready not rendered </object>调用的函数创建的<object>

时间:2012-05-25 16:48:00

标签: javascript jquery html

在我放在一起的样本中,我需要:

  1. 在$(document).ready中使用jquery POST获取我稍后使用的“票证”
  2. 在帖子成功后,调用另一个函数(“AddTicketAndRender()”)并传入该票据
  3. 在AddTicketAndRender()中,将HTML模板中的占位符值替换为传入的票证.HTML模板定义了我需要呈现的对象。
  4. 将HTML模板添加到正文并渲染:

    function addTicketAndRender(incomingTicket){
    
        //For now, just touch the spinner, don't worry about the ticket.
        var template = $('#tableauTemplate').html(),
            filledTemplate = template.replace('{placeholder}','yes');
    
    
        $('body').append( filledTemplate );}
    
  5. 我在jsfiddle工作:

    http://jsfiddle.net/vm4bG/4/

    但是,当我将HTML和JavaScript组合到一个单独的htm文件中时,我想要的可视化不会在Chrome,IE或Firefox中呈现。

    以下是HTM完全无法使用的来源。谁能看到明显错误的东西?我的标记&amp;脚本位于下方和/或此处:http://tableau.russellchristopher.org:81/rfc1.htm

    <html>
    <head>
    <script type="text/javascript" src="http://public.tableausoftware.com/javascripts/api/viz_v1.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    </head>
    
    <!-- template code follows -->
    <script type="text/template" id="tableauTemplate">
    
    <div class="tableauPlaceholder" id="tableauPlaceholder" style="width:654px; height:1469px;background-image: url('http://tableau.russellchristopher.org:81/Background.gif'); top: 0px; left: 0px; width: 100%; margin-left: 76px;">
        <object class="tableauViz" width="654" height="1469">
            <param name="host_url" value="http%3A%2F%2Fpublic.tableausoftware.com%2F"/>
            <param name="site_root" value="" />
            <param name="name" value="AnalyticsIncJavaScript&#47;AnalyticsInc" />
            <param name="tabs" value="no" />
            <param name="toolbar" value="yes" />
            <param name="static_image" value="tableau.russellchristopher.org:81/Background.gif"/>
            <param name="animate_transition" value="yes" />
            <param name="display_static_image" value="yes" />
            <param name="display_spinner" value="{placeholder}" id="display_spinner" />
            <param name="display_overlay" value="yes" />
            <param name="display_count" value="yes" />
        </object>
    </div>
    </script>
    <!-- end of template -->
    
    <body>
    <script>
    function addTicketAndRender(incomingTicket){
    
    // grab tableau template code and replace ticket placeholder with incomingTicket from $.post
    console.log("Add and Render");
    
        //For now, just touch the spinner, don't worry about the ticket.
        var template = $('#tableauTemplate').html(),
            filledTemplate = template.replace('{placeholder}','no');
    
    
        $('body').append( filledTemplate );
        console.log(incomingTicket);
        console.log("Appended.");
    
    }
    
    $(document).ready(function() {
        console.log("ready");
        var trustedURL = "http://tableau.russellchristopher.org/trusted",
            userName = "foo",
            serverURL = "http://tableau.russellchristopher.org/";
    
    
        $.post(trustedURL, {
           username: userName,
            server: serverURL,
            client_ip: "",
            target_site: ""
        }, function(response) {
            addTicketAndRender(response);
        });
    
    
    });
    
    </script>
    
    
    </body>
    
    </html>      
    

    在success函数中调用console.log正在记录正确的信息 - 所以我知道我已经到达了我需要的位置 - 但是该对象似乎没有做它需要的东西。

2 个答案:

答案 0 :(得分:5)

仅供参考,您的tableau.russellchristopher.org链接不起作用。我不知道你怎么会在jsfiddle中使用它 - 当我尝试时我得到一个交叉原点错误。

  1. 一个明显的问题是,包含模板的脚本元素位于</head><body>之间的较弱区域。把它放在body

  2. 里面
  3. 以下是我认为可能会发生的事情:看起来Tableau JavaScript API设置为在object.tableauVizDOMContentLoaded触发时处理load元素。您正在回调中将<object>标记插入到文档中以获取异步请求。所以我认为加载事件正在触发,并且Tableau API在将<object>标记插入文档之前进行初始化。

    也许为这些活动注册您自己的听众,并致电console.log(),看看他们是否在$.post回拨之前执行。

    不幸的是,执行初始化的createVizesAndStartLoading()方法(例如从文档中检索object.tableauViz元素)似乎无法访问。看起来您可以通过调用window.tableau.createViz()来添加元素,但不幸的是createVizesAndStartLoading()会对您进行一些预处理(例如设置width / height值) d要么需要复制,要么放弃。

  4. 同步检索模板

    尝试此操作而不是$.post()

    $.ajax( {
    
      url : trustedURL,
    
      data : {
    
        username : userName,
    
        server : serverURL,
    
        client_ip : "",
    
        target_site : ""
    
      },
    
      async : false
    
    } ).done( addTicketAndRender );
    

答案 1 :(得分:4)

很难从大量的代码中准确地说明你遇到的是什么,所以一般原则是:

为了查找和操作DOM元素,该元素必须存在。因此,例如,此代码将失败:

<script>$("#target").html("Updated");</script>
<p id="target">Not updated</p>

Live example | source

目标不会更新。这段代码可以使用:

<p id="target">Not updated</p>
<script>$("#target").html("Updated");</script>

Live example | source

唯一的区别是script标记位于目标之后,因此您知道当您尝试对其进行操作时,DOM中存在目标。 (这是可靠的;请参阅what Google's dev team have to say about itYUI guidelines。)

图书馆传统上包含“DOM ready”事件,因为内置的load事件的window事件直到非常非常晚才会触发在此过程中(一旦所有外部参考已加载,包括所有图像)。但人们希望尽早做事,即使图像仍在加载。 “就绪”样式事件允许脚本代码可以放在标记中的任何位置(人们喜欢将它放在head中,出于某种原因),但如果它使用“就绪”事件,则它知道它不会实际上会被调用,直到所有标记都被处理完毕。

结果是:使用ready事件,或者(更好)将依赖于元素的代码移动到之后标记中的那些元素(通常最好在关闭之前) </body>代码)。