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

Dan*_*der 0 javascript jquery function document-ready

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

我尝试制作"$("#participant")的"副本".单击(function(){"并调用它就像"Läggexitdeltagare"链接(添加用户链接).

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

URL: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>
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 6

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

处理这个的两个选择:

1.用jQuery搞定

处理它的最好方法(在我看来)是button在你的ready函数中连接使用jQuery .例如:

$("#delete_participants").click(delRow);
Run Code Online (Sandbox Code Playgroud)

2.导出该功能

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

window.delRow = delRow;
Run Code Online (Sandbox Code Playgroud)

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


附注:您不具有使用ready功能,你可以把你的脚本在页面(刚结束之前或之后的底部</body>标签),并做到这一点:

(function() {
    // Your code here
})();
Run Code Online (Sandbox Code Playgroud)

它会稍微运行,并且仍然可以访问页面上的所有DOM元素(ref | ref).但ready大多数情况下都很好.


你的评论如下:

我给了动态按钮ID"delete_participants"并创建了$("#delete_participants").click(delRow);但它不会被调用.它适用于静态按钮.

那是因为你在一个页面上不能有多个元素id.该id必须是唯一的.

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

A.单独挂钩

这只是click(function() { ... })在您创建新按钮后调用新按钮的问题,例如:

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

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

HTML:

<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>
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

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();
    });
  }

});
Run Code Online (Sandbox Code Playgroud)

实时复制

B.使用事件委派

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

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

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

$("selector_for_container").on("click", "selector_for_element", function() {
    // This will get called if the click matches the element selector
});
Run Code Online (Sandbox Code Playgroud)

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

完整的例子(使用delegate,因为很多人还没有在1.7上):

HTML:

(与上述相同)

JavaScript的:

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();
    });
  }

});
Run Code Online (Sandbox Code Playgroud)

实时复制