时间:2015-01-13 03:26:49

标签: javascript jquery html ajax

我遇到了jQuery的问题,因为它没有加载到请求的div中。

设定:

  1. 在index.php上我在4个选项卡上有4个Morris图表,一切正常。
  2. 在每个标签上都有一个列表。列表中的每个项目都是一个链接
  3. 单击链接后,选项卡中的div将重新加载新数据 通过邮件:

    $(document).ready(function () {
    $('.click5').click(function () {
        companyId = $(this).attr('id'); 
    
        $.post('./ajax/donut5.php', {
            clickthrough5: $('#company5-'+companyId+' .clickthrough5').val(),
            ref_date_from5: $('#company5-'+companyId+' .ref_date_from5').val(),
            ref_date_to5: $('#company5-'+companyId+' .ref_date_to5').val()
        },
        function (data) {
            $('.donut5').html(data);
        });
    });     
    });
    
  4. 新div包含一个后退按钮,可以让你回到第一张图的副本,但是在另一个页面上(donut1.php),为了我个人的轻松:

    $(document).ready(function () {
    $('.backref2').click(function () {
        companyId = $(this).attr('id'); 
        $.post('./ajax/donut1.php', {
            clickthrough6: $('#company6-'+companyId+' .clickthrough6').val(),
            ref_date_from6: $('#company6-'+companyId+' .ref_date_from6').val(),
            ref_date_to6: $('#company6-'+companyId+' .ref_date_to6').val()
        },
        function (data) {
            $('.donut5').html(data);
        });
    });     
    });
    
  5. 所有这些代码都可以正常工作,直到登陆donut1.php。

  6. 此时,我开始将头发中的大块头发拉几个小时,通过Chrome中的Inspect Element来识别问题。

  7. 1个秃头的人后来我意识到jQuery没有加载,尽管它在脚本标签中被正确请求。

  8. 我通过在donut1.php和donut5.php上放置以下内容来证实这一点:

    <div id="divTest1"></div>
    <script type="text/javascript">
    $("#divTest1").text("Hello, world!");
    </script>
    
  9. donut5.php显示输出正常,而donut1.php没有。

  10. 然后我尝试使用找到here的Google代码段加载外部来源和其他版本,但这仍然不起作用。

  11. 有几点需要注意: 我目前在我的页眉和页脚中加载了jquery,作为尝试解决这个问题的一部分。 由于2页donut1.php和donut5.php不包含页眉或页脚,我手动将它们包含在那里。两个文件中的确切方式相同。 donut5.php作品donut1.php没有。

    订单是index.php&gt; donut5.php&gt; donut1.php,然后你继续在donut5和donut 1之间循环 - 或者如果点击的帖子在donut1.php中工作,你会想。

    非常感谢任何帮助!

    编辑:donut1.php:

    <?php
    include("../../../includes/config.php");
    
    $selected = $_POST['clickthrough6'];
    $date_from = $_POST['ref_date_from6'];
    $date_to = $_POST['ref_date_to6'];
    
    ?>
        <script src="../../../js/jquery-1.11.0.js"></script>
    
    
    <script>
    $(document).ready(function () {
        $('.click7').click(function () {
            companyId = $(this).attr('id'); 
    
            $.post('./ajax/donut5.php', {
                clickthrough5: $('#company7-'+companyId+' .clickthrough7').val(),
                ref_date_from5: $('#company7-'+companyId+' .ref_date_from7').val(),
                ref_date_to5: $('#company7-'+companyId+' .ref_date_to7').val()
            },
            function (data) {
                $('.donut5').html(data);
            });
        });     
    });
    
    
    </script>
    
    <div id="tabs2">
        <div id="tabs-1" class="donut5">
    
                <h4>Top 5 Referrers - Quotes <br /><small>Total number of Quotes between <?php echo date("d/m/Y", $date_from); ?> to <?php echo date("d/m/Y", $date_to); ?></small></h4>
    
            <div class="statgrid">
    
    <div id="divTest1"></div>
    <script type="text/javascript">
    $("#divTest1").text("Hello, world!");
    </script>
    
                <?php $quotes_q="SELECT 
                c.case_id,
                co.name AS company_name, 
                co.company_id AS company_id,
                COUNT(c.case_id) 'quote_count' 
                FROM 
                (`case` c,
                `panel_company` pc,
                `panel` p)
                LEFT JOIN company co ON (co.company_id = pc.company_id) 
                WHERE pc.panel_id = " .$RegisteredUser['panel_id']. " AND
                p.company_id = pc.company_id AND
                c.panel_id = p.panel_id AND 
                c.insert_date > ".$date_from. " AND 
                c.insert_date < ".$date_to. "
                GROUP BY p.panel_id
                ORDER BY quote_count DESC, co.company_id
                LIMIT 5"; 
                $result=$mysqli->query($quotes_q); ?>
    
                <div class="col-2-6">
                    <div id="morris-donut-chart6"></div>
                </div>
            </div>
            <div class="statgrid">
                <?php while ($row=$result->fetch_array()) { ?>
                <div class="col-4-6">
                <div id="company7-<?php echo $row['company_id'];?>">
                    <input type="hidden" class="ref_date_from7" value="<?php echo $date_from; ?>" />
                    <input type="hidden" class="ref_date_to7" value="<?php echo $date_to; ?>" />
                    <input type="hidden" class="clickthrough7" value="<?php echo $row['company_id'] ?>" />
                            <a><div id="<?php echo $row['company_id'];?>" class="click7 col-5-6"><?php echo $row['company_name']; ?></div></a>
                            <div class="col-1-6"><?php echo $row['quote_count']; ?></div>
                </div>
    
                </div>
                <?php } ?>
    
            </div>
        </div>
    
    </div>
    <?php
        $quotes_q = "SELECT 
                c.case_id,
                co.name AS company_name, 
                COUNT(c.case_id) 'quote_count' 
                FROM 
                (`case` c,
                `panel_company` pc,
                `panel` p)
                LEFT JOIN company co ON (co.company_id = pc.company_id) 
                WHERE pc.panel_id = ".$RegisteredUser['panel_id']." AND
                p.company_id = pc.company_id AND
                c.panel_id = p.panel_id AND 
                c.insert_date > ".$date_from." AND 
                c.insert_date < ".$date_to."
                GROUP BY p.panel_id
                ORDER BY quote_count DESC, co.company_id
                LIMIT 5";
    
        $result = $mysqli->query($quotes_q);    
    
    ?>
    <script>
        var donut_data6 = [
        <?php while ($row = $result->fetch_array()) { ?>
        {
                label: '<?php echo substr($row['company_name'],0,15); ?>',
                value: '<?php echo $row['quote_count']; ?>'
        },
        <?php } ?>
        ];
    
        var donut6 = {
            element: 'morris-donut-chart6',
            data: donut_data6,
            resize: false
            }
    
        donut6 = Morris.Donut(donut6)
    
    </script>
    

    EDIT2: 不太确定,如果这有所不同,但在网络选项卡中我有2个jquery列表,从标题加载304 Not Modified加载的第二个和加载调用donut5.php的第二个加载为200 OK。似乎在此之后我不能再次请求jquery吗?

    EDIT3:在donut1.php中,除了jquery脚本请求和我试图检索的div中的Hello World之外,我已经删除了所有内容。网络选项卡仍显示jquery未加载。奇怪的是我有这个确切的设置,减去图表,在同一页面上工作(当然是不同的div类),这确实加载了jquery。

    EDIT4:替代jQuery for JS作为测试而不是基本的独立JS将起作用,补充说:

    <p id="demo"></p>
    
    <script>
    document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
    

    没什么:( - 在JS世界中循环

    EDIT5:假设<script>是一个HTML标记,所以也在其中循环。

    EDIT6:将console.logo(数据)添加到上面列表项4中的函数时,我得到了以下内容(显然我已经排除了很多测试内容:

        <script src="../../../js/jquery-1.11.0.js"></script>
        <script src="../../../js/jquery-ui.js"></script>
    
    <!--
    <script>
    $(document).ready(function () {
        $('.click7').click(function () {
            companyId = $(this).attr('id'); 
    
            $.post('./ajax/donut5.php', {
                clickthrough5: $('#company7-'+companyId+' .clickthrough7').val(),
                ref_date_from5: $('#company7-'+companyId+' .ref_date_from7').val(),
                ref_date_to5: $('#company7-'+companyId+' .ref_date_to7').val()
            },
            function (data) {
                $('.donut5').html(data);
            });
        });     
    });
    </script>
    -->
    
    <div id="tabs2">
        <div id="tabs-1" class="donut5">
    
    <p id="demo"></p>
    
    <script>
    document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
    
    <div id="divTest1"></div>
    <script type="text/javascript">
    $("#divTest1").text("Hello, world!");
    </script>
    
        </div>
    
    </div>
    

    EDIT7:

    在此处放置代码以确认我是否正确填写了KevinB的建议。

    var
        contentSelector = '.donut5',
        $content = $(contentSelector),
        contentNode = $content.get(0);
    
    var documentHtml = function (html) {
        // Prepare
        var result = String(html)
            .replace(/<\!DOCTYPE[^>]*>/i, '')
        .replace(/<(html|head|body|title|meta|script)([\s\>])/gi,'<div class="document-$1"$2')
            .replace(/<\/(html|head|body|title|meta|script)\>/gi, '</div>');
    
        // Return
        return $.trim(result);
    };
    
    
    
    $(document).ready(function () {
        $('.click5').click(function () {
            companyId = $(this).attr('id');
    
            $.post('./ajax/donut5.php', {
                clickthrough5: $('#company5-' + companyId + ' .clickthrough5').val(),
                ref_date_from5: $('#company5-' + companyId + ' .ref_date_from5').val(),
                ref_date_to5: $('#company5-' + companyId + ' .ref_date_to5').val()
            },
    
            function (data) {
    
    
                var
                    $data = $(documentHtml(data)),
                    $dataBody = $data.find('.donut5'),
                    $dataContent = $dataBody.find(contentSelector),
                    $menuChildren, contentHtml, $scripts;
    
                // Fetch the scripts
                $scripts = $dataContent.find('.document-script');
                if ($scripts.length) {
                    $scripts.detach();
                }
    
                // Fetch the content
                contentHtml = $dataContent.html() || $data.html();
                $scripts.each(function () {
                    var $script = $(this),
                        scriptText = $script.text(),
                        scriptNode = document.createElement('script');
                    if ($script.attr('src')) {
                        if (!$script[0].async) {
                            scriptNode.async = false;
                        }
                        scriptNode.src = $script.attr('src');
                    }
                    scriptNode.appendChild(document.createTextNode(scriptText));
                    contentNode.appendChild(scriptNode);
                });
                console.log(data);
            });
        });
    });
    

    EDIT8:

    在EDIT7中尝试上面的代码后,.donut5不再被从donut5.php拉到最初工作的index.php。单击donut5.php的链接时,我可以看到jquery在网络选项卡上不再复制(即使对它的调用仍然存在)。目前要么我假设我没有在上面正确映射div,因为我删除了:first的部分类查找代码,因为我觉得它不是必需的,或者不知何故我设法让事情变得更糟!

1 个答案:

答案 0 :(得分:0)

当你将htmlstring传递给.html时,会发生以下两种情况之一。它可以使用.innerHTML插入,也可以使用.empty().append(htmlString)插入。选择哪一个是基于传入的htmlstring的复杂性。

如果它相对简单,将使用.innerHTML,脚本将以您期望的方式执行。

但是,如果它更复杂,则首先解析元素并将其附加到docFragment,然后再附加到文档。这个中间步骤是导致您的问题的原因,因为javascript将在元素属于document之前执行。

修复此问题的唯一方法是强制延迟javascript的执行,方法是编写javascript,使其执行在后来被调用的回调中,或者在追加之前从htmlstring中删除javascript然后再执行它。

以下是前者的一个例子:

(function divTestLooper () {
    if (!$("#divTest1").length) {
        // the element didn't exist, lets wait a little longer...
        return setTimeout(divTestLooper, 10);
    }
    $("#divTest1").text("Hello, world!");
})();

以下是后者的一个例子:
https://github.com/browserstate/ajaxify/blob/master/ajaxify-html5.js#L60-L70

https://github.com/browserstate/ajaxify/blob/master/ajaxify-html5.js#L123-L135

https://github.com/browserstate/ajaxify/blob/master/ajaxify-html5.js#L158-L167


当然,最好的解决方案可能是完全避免这个问题,不包括你的偏见中的javascript。