document.ready 中的调用函数不起作用

发布于 2024-12-25 17:51:34 字数 5309 浏览 1 评论 0 原文

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

我尝试制作“$(”#participants”).click(function() {”的“副本”并像“Läggtil deltagare”链接(添加用户链接)一样调用它。

我如何最好地解决这个问题为什么你不能调用 document.ready 中的函数,为什么我的参与者 click.function 不起作用(我在代码示例中没有它,我将其命名为"$("#deleterow").click(function() 并将按钮的 id 设置为 deleterow)

URL: http://min.xn--spyp-toa.se/addrows.php (某些 DNS 服务器有此问题,请运行 googles 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>

I want to be able to call a function from a link (this function will delete the corresponding row). If I place the function inside document ready it wont load upon call. But it works while outside. The function is delRow(id) located at the end of .

I tried making a 'copy' of "$("#participants").click(function() {" and calling it just like the "Lägg till deltagare" link (add user link).

How do I solve this in the best way? And Why cant you call functions inside document.ready and why wont my copy of the participants click.function work? (I dont have it in the code example, i named it like "$("#deleterow").click(function() and set the id of the button to deleterow)

URL: http://min.xn--spyp-toa.se/addrows.php (Some DNS servers have problem with this, run googles DNS instead! 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ä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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光无声 2025-01-01 17:51:34

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

处理这个问题有两种选择:

1. 使用 jQuery 连接起来

处理这个问题的最佳方法(在我看来)是在您的 readybutton代码>函数。例如:

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

2. 仅导出该函数

来创建一个指向 delRow 的全局:

window.delRow = delRow;

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


旁注:您没有使用ready函数,您可以将脚本放在页面底部(就在结束之前或之后) 标签)并执行以下操作:

(function() {
    // Your code here
})();

它将运行得稍微更快,并且仍然可以访问页面上的所有 DOM 元素(参考 | 参考)。但 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...*/);

例如,这里是一个完整的示例:

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>

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

});

直播B.

使用事件委托

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

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

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

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

请注意,参数略有不同。)

完整示例(使用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();
    });
  }

});

实时复制

When you use old-style DOM0 handler hookup (onclick="..."), any functions you reference in that string must be globals. Your delRow function isn't a global, it's contained by the function you're passing into ready — which is a good thing, the global namespace is already too full.

Two choices for dealing with this:

1. Hook things up with jQuery

The best way (in my view) to deal with it is to hook up your button using jQuery from within your ready function. E.g.:

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

2. Export just that function

Alternatively, you could make a global that points to delRow by doing this within the ready function:

window.delRow = delRow;

That works because all global variables are properties of the window object in browsers, so by assigning a reference to delRow to the delRow property on window, you're explicitly making it available in the global namespace (without cluttering up the global namespace with any of your other functions). Then the onclick="..." handler will be able to see it. But I wouldn't advocate using globals if you can avoid it. It's a useful bridging technique, though, as you transition from the old style to the newer style.


Side note: You don't have to use the ready function, you can just put your script at the bottom of the page (just before or after the ending </body> tag) and do this:

(function() {
    // Your code here
})();

It will run slightly sooner, and still have access to all of the DOM elements on the page (ref | ref). But ready is mostly fine too.


Re your comment below:

I´ve given dynamic buttons the ID "delete_participants" and created the $("#delete_participants").click(delRow); but it aint getting called. It works for the static button tho.

That's because you can't have more than one element on a page with the same id. The id values must be unique.

If you're going to be adding and removing rows, and if you're using jQuery to hook things up, you have two additional choices:

A. Hook Them Up Individually

This is just a matter of calling click(function() { ... }) on the new button once you've created it, e.g.:

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

So for instance, here's a complete example:

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>

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

});

Live copy

B. Use Event Delegation

But in cases like this, another technique is frequently better: Event delegation. In event delegation, you hook the event ("click") on some container of all of the things that might receive that click, and then when the click happens check to see if the event has passed through any of the relevant elements (because most events, including "click", "bubble" from the element on which the click actually occurred up to its parent, grandparent, and other ancestors). jQuery makes delegation dead easy, using delegate:

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

or, as of 1.7 or later, using one of the several variants of on:

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

(Note that the order of arguments is slightly different.)

Complete example (using delegate, since a lot of people aren't on 1.7 yet):

HTML:

(Same as above)

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

});

Live copy

掀纱窥君容 2025-01-01 17:51:34

“您已经在闭包中定义了该函数,因此在该就绪函数之外无法访问它”

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

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

"You've defined the function within a closure, so it's not accessible outside of that ready function"

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

You should always put your functions outside the document ready closure for them to be accessible within the global scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文