Вызов функции внутри документа. Уже не будет работать - PullRequest
0 голосов
/ 10 января 2012

Я хочу иметь возможность вызывать функцию по ссылке (эта функция удалит соответствующую строку). Если я помещу функцию в готовый документ, она не будет загружаться при вызове. Но это работает пока на улице. Функция delRow (id) находится в конце.

Я попытался сделать копию "$ (" # участники "). Click (function () {" и вызвал ее так же, как ссылку "Lägg till deltagare" (добавить ссылку пользователя).

Как мне решить это наилучшим образом? И почему вы не можете вызывать функции внутри document.ready и почему не работает моя копия click.function участников? (У меня его нет в примере кода, я назвал его как "$ (" # deleterow "). Click (function () и установил id кнопки в deleteterow)

URL: http://min.xn - spyp-toa.se/addrows.php (У некоторых DNS-серверов есть проблема с этим, вместо этого запускайте googles DNS!

<?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 ]

6 голосов
/ 10 января 2012

Когда вы используете подключение обработчика DOM0 старого стиля (onclick="..."), все функции, на которые вы ссылаетесь в этой строке, должны быть глобальными.Ваша delRow функция не является глобальной, она содержится в функции, которую вы передаете в ready - что хорошо, глобальное пространство имен уже переполнено.

Два варианта работы сэто:

1.Подключите вещи с помощью jQuery

Лучший способ (на мой взгляд) справиться с этим - подключить ваш button с помощью jQuery из вашей функции ready.Например:

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

2.Экспортируйте только эту функцию

В качестве альтернативы, вы могли бы создать глобал, который указывает на delRow, выполнив это в функции ready:

window.delRow = delRow;

Это работаетпоскольку все глобальные переменные являются свойствами объекта window в браузерах, поэтому, присваивая ссылку на delRow свойству delRow в window, вы явно делаете его доступным в глобальном пространстве имен (без загроможденияглобальное пространство имен с любой из ваших других функций).Тогда обработчик onclick="..." сможет увидеть его.Но я бы не рекомендовал использовать глобальные переменные, если вы можете избежать этого.Тем не менее, это полезный метод соединения, когда вы переходите от старого стиля к новому.


Примечание: у вас нет для использования функции ready, вы можете просто поместить свой скрипт внизу страницы (непосредственно перед или после конечного тега </body>) и сделать это:

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

Он будет запускаться немного раньше,и по-прежнему иметь доступ ко всем элементам DOM на странице ( ref | ref ).Но ready в основном тоже нормально.


Ваш комментарий ниже:

Я дал динамическим кнопкам идентификатор "delete_participants" и создал $("#delete_participants").click(delRow);, ноэто не называют.Это работает для статической кнопки tho.

Это потому, что вы не можете иметь более одного элемента на странице с одинаковым 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();
    });
  }

});

Живая копия

0 голосов
/ 10 января 2012

«Вы определили функцию в замыкании, поэтому она недоступна за пределами этой функции готовности»

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

Вы всегда должны размещать свои функции за пределами готового документа, чтобы они были доступны в глобальной области видимости.

...