在document.ready内部调用函数不会工作

时间:2012-01-10 18:03:44

标签: javascript jquery function document-ready

我希望能够从链接中调用函数(此函数将删除相应的行)。如果我将函数放在文档中,它就不会在调用时加载。但它在外面工作。该函数是位于末尾的delRow(id)。

我尝试制作“$(”#participant“”)的'副本'。点击(function(){“并调用它就像”Läggexitdeltagare“链接(添加用户链接)。

如何以最佳方式解决此问题?为什么你不能调用document.ready中的函数以及为什么我的副本没有参与者click.function工作? (我在代码示例中没有它,我把它命名为“$(”#deleterow“)。click(function()并将按钮的id设置为deleterow)

网址:http://min.xn--spyp-toa.se/addrows.php(某些DNS服务器存在此问题,请改为运行谷歌DNS!8.8.8.8)

<?php 
//Inkluderar fil för inläsning av databasinfo.
require("core.inc");       
?>

    <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>

    <script type="text/javascript">

        $(document).ready(function () {

         //Denna kod ska hämta users i databasen till js-arrayen users
           var users = new Array();

            $.ajax({
                url: 'getuser.php',
                dataType: 'json',
                error: function(){alert("Kunde inte hämta data från databas");},
                success: function(data){
                    users = data;
                }
            });

        //Denna kod lägger till en ny rad
            var rowCount = 1; // Räknare som räknar hur många rader man lagt till
            var selectedUsers = new Array(); //Denna array innehåller användare man lagt till

            $("#participants").click(function() {

                var participantSelect = document.getElementById('participantSelect'); //Denna variabel håller värdet från selecten

                //En funktion som loopar fram användarna i databasen till <option> taggar
                function addOption(){

                    var option; //Denna variabel lagrar alla options som genereras i loopen

                    for (var i=0; i < users.length-1; i++)  {

                        var user = users[i].id;

                        if(jQuery.inArray(user, selectedUsers) > -1) {

                        }
                        else{
                           option += ('<option value="'+users[i].id+'">'+users[i].name+'</option>'); 
                        }
                    }
                    return option; //Skickar alla genererade <option>-taggar till append-scriptet
                }

                //Funktionen som uppdaterar <select>-satsen
                function updateSelect(){
                    $('#participantSelect').replaceWith('<select name="participantSelect" id="participantSelect">'+addOption()+'</select>');
                }

                //Function som matas in i apenden, den plockar ut namnet som hör till ID som kommer från selecten
                function name(){

                    //kör igenom arraeyn men avslutar när den hittar en träff
                    for(var i=0; users.length; i++){

                        if(users[i].id == participantSelect.value){ //Om användar ID är samma som ID från select

                            selectedUsers.push(users[i].id); //Denna lägger till valda användare i en array för filtrering av redan använda användare

                            //Denna funktion anropar koden som genererar om <select> och utelämnar redan valda användare
                            updateSelect();

                            return users[i].name; //Return i if-satsen för att avbryta vid träff.
                        } 
                    }
                }

                //Skriver in en input som är read-only med den valda användaren
                $('#container').append('<input type="text" name="participant_'+rowCount+'" id="'+participantSelect.value+'" value="'+name()+'" class="participant_1" readonly="readonly" /> <a href="#" name="participant_'+rowCount+'" id="'+rowCount+'" class="participant_1" onclick="bajs(this.name)">Ta bort deltagare</a><br>');

               rowCount++;                   
            });

            //Denna kod tar bort redan inmatad användare och lägger tillbaka denne i <select>
                function delRow(id){
                    alert(id);
                    alert("test");
                }
        });

    </script>

    <!-- Här väljer man vilka användare som deltagit, sedan trycker man på lägg till-knappen -->
    <select name="participantSelect" id="participantSelect">
                <?php

                $result = mysql_query("SELECT id, name FROM user");

                while ($db_field = mysql_fetch_assoc($result)) {
                    echo '<option value="'.$db_field['id'].'">'.$db_field['name'].'</option>';
                }

                mysql_free_result($result);

              ?>
    </select>

    <!-- Knapp för att lägga till ny rad inom container-diven -->
    <a href="#" id="participants" class="myButton">L&auml;gg till deltagare</a>

    <!-- Container diven hit vad alla användare kommer läggas till-->
    <h2>Deltagare:</h2>
    <div id="container" class="container">
   <!-- Här kommer allt läggas in -->
    </div>  

    <button name="participant_1" id="delete_participants" onclick="delRow()">Ta bort deltagare</button><br>

2 个答案:

答案 0 :(得分:6)

当您使用旧式DOM0处理程序连接(onclick="...")时,您在该字符串中引用的任何函数都必须是全局变量。您的delRow函数不是全局函数,它包含在您传递给ready的函数中 - 这是一件好事,全局命名空间已经太满了。

处理此问题的两种选择:

1。使用jQuery搞砸了事情

处理它的最佳方法是在button函数中使用jQuery连接ready。 E.g:

$("#delete_participants").click(delRow);

2。只导出该功能

或者,您可以通过在delRow函数中执行此操作来创建指向ready的全局:

window.delRow = delRow;

这是有效的,因为所有全局变量都是浏览器中window对象的属性,因此通过将delRow的引用分配给delRow上的window属性,你可以'显式使其在全局命名空间中可用(不会使用任何其他函数混淆全局命名空间)。然后onclick="..."处理程序将能够看到它。但是如果你能避免它,我不会提倡使用全局变量。但是,当您从旧样式过渡到新样式时,它是一种有用的桥接技术。


附注:你没有拥有来使用ready功能,你可以将你的脚本放在页面的底部(在结束之前或之后{{1}标签)并执行此操作:

</body>

它会稍早运行 ,并且仍然可以访问页面上的所有DOM元素(ref | ref)。但是(function() { // Your code here })(); 也很好。


重新评论以下内容:

  

我已经为动态按钮提供了ID“delete_participants”并创建了ready,但它不会被调用。它适用于静态按钮。

这是因为您在页面上不能有多个具有相同$("#delete_participants").click(delRow);的元素。 id必须是唯一的。

如果您要添加和删除行,并且如果您使用jQuery进行连接,则还有两个选择:

一种。单独挂钩

这只是在您创建新按钮后调用id的问题,例如:

click(function() { ... })

例如,这是一个完整的例子:

HTML:

var tr = '<tr><td><input type="button" name="delete"></td></tr>';
tr.find('input').click(delRow);
tr.appendTo(/* ...presumably a table body or something...*/);

JavaScript的:

<table id="participants">
  <tfoot>
    <tr>
      <td colspan='2'>
        <input type="button" name="add" value="Add Participant">
      </td>
    </tr>
  </tfoot>
  <tbody>
    <tr>
      <td>
        Joe Bloggs
      </td>
      <td>
        <input type="button" name="delete" value="Delete">
      </td>
    </tr>
  </tbody>
</table>

Live copy

B中。使用事件委派

但在这种情况下,另一种技术往往更好:事件委托。在事件委托中,您将事件(“单击”)挂钩在可能接收该点击的所有事物的某个容器上,然后在点击发生时检查事件是否已通过任何事件相关元素(因为大多数事件,包括“点击”,“泡沫”,从实际发生点击的元素到其父,祖父母和其他祖先)。 jQuery使用delegate

使委派变得容易
jQuery(function($) {

  $("#participants")
    .delegate('input[name="add"]', "click", addParticipant)
    .delegate('input[name="delete"]', "click", delParticipant);

  function addParticipant() {
    var td, tr, name;

    // Obviously you'd use something more modern than `prompt`
    name = prompt("Name for new participant: ", "");
    if (name) {
      // And this code is no thing of beauty, either, but you get the idea
      td = $('<td>').text(name);
      tr = $('<tr>');
      tr.append(td);
      tr.append('<td><input type="button" name="delete" value="Delete"></td>');
      tr.hide();
      $("#participants tbody").append(tr);
      tr.fadeIn();
      // Note we don't have to do anything to hook the new button;
      // delegation handles that
    }
  }

  function delParticipant() {
    var tr = $(this).closest('tr');
    tr.fadeOut(function() {
      tr.remove();
    });
  }

});

或者,从1.7或更高版本开始,使用on的几种变体之一:

$("selector_for_container").delegate("selector_for_element", "click", function() {
    // This will get called if the click matches the element selector
});

(请注意,参数的顺序略有不同。)

完整示例(使用$("selector_for_container").on("click", "selector_for_element", function() { // This will get called if the click matches the element selector }); ,因为很多人还没有使用1.7):

HTML:

(与上述相同)

JavaScript的:

delegate

Live copy

答案 1 :(得分:0)

“你已经在一个闭包中定义了这个函数,所以它不能在那个就绪函数之外访问”

http://forum.jquery.com/topic/call-functions-outside-document-ready

您应始终将您的函数置于文档就绪闭包之外,以便在全局范围内访问它们。