addEventListener() 附加到多个按钮,但仅触发一次

发布于 2024-08-07 18:21:15 字数 10568 浏览 5 评论 0原文

我正在用 PHP/FBJS 编写 Facebook 应用程序。我有一些代码,将 addEventListener() 附加到两个按钮。当我运行应用程序时,我单击的第一个按钮会触发 addEventListener() 并按预期调用事件处理程序。但是,如果我单击第二个按钮或再次单击同一按钮,则不会调用事件处理程序。这是我的代码:

//PHP
      public function loadCargoDialogFbjsAction() {
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        $loadableCargo = $this->getRequest()->getPost('loadableCargo');
        $fbjs =
          '<div id="load_cargo_select">
            <form id="load_cargo_select_form" action="" method="POST">
              <p>Your train has stopped in the city of ' . $loadableCargo['city'] . '</p>
              <p>' . $loadableCargo['city'] . ' produces the following goods:</p>
              <ul>';
        if(count($loadableCargo['city_goods']) <= 0) {
          $fbjs .= '<li>None</li>';
        } else {
          foreach($loadableCargo['city_goods'] as $goods) {
            $fbjs .= '<li>' . $goods['name'] . '</li>';
          }
        }
        $fbjs .=
              '</ul>
              <p>Your train is hauling the following goods:</p>
              <ul>';
              if(count($loadableCargo['train_goods']) <= 0) {
                $fbjs .= '<li>None</li>';
              } else {
                foreach($loadableCargo['train_goods'] as $goods) {
                  $fbjs .= '<li>' . $goods['name'] . '</li>';
                }
              }
        $fbjs .=
              '</ul>
              <p>What would you like to do?</p>
              <input type="button" id="load-new-submit" name="load-cargo-new" value="Load new goods" />
              &nbsp;&nbsp;
              <input type="button" id="discard-existing-submit" name="load-cargo-discard" value="Discard existing goods" />
            </form>
          </div>';

        echo $fbjs;
      }


// JavaScript/FBJS
    function loadCargo() {
      var actionPrompt = document.getElementById('action-prompt');
      actionPrompt.setTextValue('Loading cargo...');

      var ajax = new Ajax();
      ajax.responseType = Ajax.JSON;
      ajax.ondone = function(data) {
    //debugger;
        ajax.responseType = Ajax.FBML;
        ajax.ondone = function(fbjsData) {
    //debugger;
          if(data.loadableCargo.length == 0) {
            moveTrainManual();
          } else {
            var dialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');

            var dlgBtnNew = document.getElementById('load-new-submit');
            dlgBtnNew.cityId = data.loadableCargo.city_id;
            dlgBtnNew.trainId = data.loadableCargo.train_id;
            dlgBtnNew.addEventListener('click', cargoEventHandler); //loadNewCargo);

            var dlgBtnDiscard = document.getElementById('discard-existing-submit');
            dlgBtnDiscard.cityId = data.loadableCargo.city_id;
            dlgBtnDiscard.trainId = data.loadableCargo.train_id;
            dlgBtnDiscard.addEventListener('click', cargoEventHandler); //discardExistingCargo);

            dialog.onconfirm = function() {
              // Submit the form if it exists, then hide the dialog.
              dialog.hide();
              actionPrompt = document.getElementById('action-prompt');
              actionPrompt.setInnerXHTML('<span><div id="action-text">'+
                'The "Load cargo" dialog has been minimized'+
                '</div>'+
                '<div id="action-end">'+
                '<form action="" method="POST">'+
                '<input type="button" value="Maximize" id="next-phase" onclick="loadCargo();" />'+
                '</form>'+
                '</div></span>');
              actionButton = document.getElementById('next-phase');
              actionButton.setValue('Maximize');
              actionButton.addEventListener('click', loadCargoEventHandler);
            };
            dialog.oncancel = function() {
              moveTrainManual();
            }
          }
        }
        ajax.post(baseURL + '/turn/load-cargo-dialog-fbjs', data);
      }
      ajax.post(baseURL + '/turn/load-cargo');
    }

    function cargoEventHandler(evt) {
      //new Dialog().showMessage('loadNewCargo', 'city id='+cityId+', train id='+trainId);
    //debugger;
      cityId = evt.target.cityId;
      trainId = evt.target.trainId;

      switch(evt.target.getId()) {
        case 'load-new-submit':
          ajax = new Ajax();
          ajax.responseType = Ajax.JSON;
          param = { 'load-cargo-submit': "Load new goods", 'city-id': cityId, 'train-id': trainId };
          ajax.ondone = function(data) {
            openCargoHolds = data.openCargoHolds;
            cargoHoldsUsed = 0;
            ajax.responseType = Ajax.FBML;
            param = { 'openCargoHolds': data.openCargoHolds, 'cityGoods': data.cityGoods, 'trainId': data.trainId };
            ajax.ondone = function(fbjsData) {
        //debugger;
              var dialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Load cargo', 'Cancel');
              dialog.onconfirm = function() {
                var goods = [];
                var goodsIds = [];
                numGoods = document.getElementById('goods-count').getValue();

                for(var i = 0; i < numGoods; i++) {
                  j = i + 1;
                  goods[i] = document.getElementById('goods-' + j).getValue();
                  goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
                }
                var trainId = document.getElementById('train-id').getValue();
                param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
                ajax.responseType = Ajax.JSON;
                ajax.ondone = function(data) {
                  loadCargo();
                }
                ajax.post(baseURL + '/turn/do-load-cargo-new', param);
                //dialog.hide();
              };
              dialog.oncancel = function() {
                loadCargo();
              }
            }
            ajax.post(baseURL + '/turn/load-cargo-new-dialog-fbjs', param);
          }
          ajax.post(baseURL + '/turn/load-cargo-select', param);
          break;
        case 'discard-existing-submit':
          ajax = new Ajax();
          ajax.responseType = Ajax.JSON;
          param = { 'load-cargo-submit': "Discard existing goods", 'city-id': cityId, 'train-id': trainId };
          ajax.ondone = function(data) {
            ajax.responseType = Ajax.FBML;
            param = { 'openCargoHolds': data.openCargoHolds, 'trainGoods': data.trainGoods, 'trainId': data.trainId };
            ajax.ondone = function(fbjsData) {
              var dialog = new Dialog().showChoice('Discard Cargo', fbjsData, 'Discard cargo', 'Cancel');
              dialog.onconfirm = function() {
                var goods = [];
                var goodsIds = [];
                numGoods = document.getElementById('goods-count').getValue();
                for(var i = 0; i < numGoods; i++) {
                  j = i + 1;
                  goods[i] = document.getElementById('goods-' + j).getValue();
                  goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
                }
                var trainId = document.getElementById('train-id').getValue();
                param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
                ajax.responseType = Ajax.JSON;
                ajax.ondone = function(data) {
                  loadCargo();
                }
                ajax.post(baseURL + '/turn/do-load-cargo-discard', param);
                //dialog.hide();
              };
              dialog.oncancel = function() {
                loadCargo();
              }
            }
            ajax.post(baseURL + '/turn/load-cargo-discard-dialog-fbjs', param);
          }
          ajax.post(baseURL + '/turn/load-cargo-select', param);
          break;
      }
      return false;
    }

任何帮助将不胜感激。谢谢!

@Tim,

我按如下方式更改了 loadCargo() 函数,以防止重复这些元素,但我仍然遇到与以前相同的问题。

var loadCargoDialog;

function loadCargo() {
  var actionPrompt = document.getElementById('action-prompt');
  actionPrompt.setTextValue('Loading cargo...');

  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;
  ajax.ondone = function(data) {
//debugger;
    ajax.responseType = Ajax.FBML;
    ajax.ondone = function(fbjsData) {
//debugger;
      if(data.loadableCargo.length == 0) {
        moveTrainManual();
      } else {
        if(loadCargoDialog == null) {
          loadCargoDialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');

          var dlgBtnNew = document.getElementById('load-new-submit');
          dlgBtnNew.cityId = data.loadableCargo.city_id;
          dlgBtnNew.trainId = data.loadableCargo.train_id;
          dlgBtnNew.addEventListener('click', cargoEventHandler, true); //loadNewCargo);

          var dlgBtnDiscard = document.getElementById('discard-existing-submit');
          dlgBtnDiscard.cityId = data.loadableCargo.city_id;
          dlgBtnDiscard.trainId = data.loadableCargo.train_id;
          dlgBtnDiscard.addEventListener('click', discardExistingCargo, true);

        } else {
          loadCargoDialog.showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');
        }

        loadCargoDialog.onconfirm = function() {
          // Submit the form if it exists, then hide the dialog.
          loadCargoDialog.hide();
          actionPrompt = document.getElementById('action-prompt');
          actionPrompt.setInnerXHTML('<span><div id="action-text">'+
            'The "Load cargo" dialog has been minimized'+
            '</div>'+
            '<div id="action-end">'+
            '<form action="" method="POST">'+
            '<input type="button" value="Maximize" id="next-phase" onclick="loadCargo();" />'+
            '</form>'+
            '</div></span>');
          actionButton = document.getElementById('next-phase');
          actionButton.setValue('Maximize');
          actionButton.addEventListener('click', loadCargoEventHandler);
        };
        loadCargoDialog.oncancel = function() {
          moveTrainManual();
        }
      }
    }
    ajax.post(baseURL + '/turn/load-cargo-dialog-fbjs', data);
  }
  ajax.post(baseURL + '/turn/load-cargo');
}

I am writing a Facebook app in PHP/FBJS. I have some code where I attach an addEventListener() to two buttons. When I run the app, the first button I click on fires the addEventListener() and the event handler is invoked as expected. But if I click on the second button or click on the same button again, the event handler is not invoked. Here is my code:

//PHP
      public function loadCargoDialogFbjsAction() {
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender();

        $loadableCargo = $this->getRequest()->getPost('loadableCargo');
        $fbjs =
          '<div id="load_cargo_select">
            <form id="load_cargo_select_form" action="" method="POST">
              <p>Your train has stopped in the city of ' . $loadableCargo['city'] . '</p>
              <p>' . $loadableCargo['city'] . ' produces the following goods:</p>
              <ul>';
        if(count($loadableCargo['city_goods']) <= 0) {
          $fbjs .= '<li>None</li>';
        } else {
          foreach($loadableCargo['city_goods'] as $goods) {
            $fbjs .= '<li>' . $goods['name'] . '</li>';
          }
        }
        $fbjs .=
              '</ul>
              <p>Your train is hauling the following goods:</p>
              <ul>';
              if(count($loadableCargo['train_goods']) <= 0) {
                $fbjs .= '<li>None</li>';
              } else {
                foreach($loadableCargo['train_goods'] as $goods) {
                  $fbjs .= '<li>' . $goods['name'] . '</li>';
                }
              }
        $fbjs .=
              '</ul>
              <p>What would you like to do?</p>
              <input type="button" id="load-new-submit" name="load-cargo-new" value="Load new goods" />
                
              <input type="button" id="discard-existing-submit" name="load-cargo-discard" value="Discard existing goods" />
            </form>
          </div>';

        echo $fbjs;
      }


// JavaScript/FBJS
    function loadCargo() {
      var actionPrompt = document.getElementById('action-prompt');
      actionPrompt.setTextValue('Loading cargo...');

      var ajax = new Ajax();
      ajax.responseType = Ajax.JSON;
      ajax.ondone = function(data) {
    //debugger;
        ajax.responseType = Ajax.FBML;
        ajax.ondone = function(fbjsData) {
    //debugger;
          if(data.loadableCargo.length == 0) {
            moveTrainManual();
          } else {
            var dialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');

            var dlgBtnNew = document.getElementById('load-new-submit');
            dlgBtnNew.cityId = data.loadableCargo.city_id;
            dlgBtnNew.trainId = data.loadableCargo.train_id;
            dlgBtnNew.addEventListener('click', cargoEventHandler); //loadNewCargo);

            var dlgBtnDiscard = document.getElementById('discard-existing-submit');
            dlgBtnDiscard.cityId = data.loadableCargo.city_id;
            dlgBtnDiscard.trainId = data.loadableCargo.train_id;
            dlgBtnDiscard.addEventListener('click', cargoEventHandler); //discardExistingCargo);

            dialog.onconfirm = function() {
              // Submit the form if it exists, then hide the dialog.
              dialog.hide();
              actionPrompt = document.getElementById('action-prompt');
              actionPrompt.setInnerXHTML('<span><div id="action-text">'+
                'The "Load cargo" dialog has been minimized'+
                '</div>'+
                '<div id="action-end">'+
                '<form action="" method="POST">'+
                '<input type="button" value="Maximize" id="next-phase" onclick="loadCargo();" />'+
                '</form>'+
                '</div></span>');
              actionButton = document.getElementById('next-phase');
              actionButton.setValue('Maximize');
              actionButton.addEventListener('click', loadCargoEventHandler);
            };
            dialog.oncancel = function() {
              moveTrainManual();
            }
          }
        }
        ajax.post(baseURL + '/turn/load-cargo-dialog-fbjs', data);
      }
      ajax.post(baseURL + '/turn/load-cargo');
    }

    function cargoEventHandler(evt) {
      //new Dialog().showMessage('loadNewCargo', 'city id='+cityId+', train id='+trainId);
    //debugger;
      cityId = evt.target.cityId;
      trainId = evt.target.trainId;

      switch(evt.target.getId()) {
        case 'load-new-submit':
          ajax = new Ajax();
          ajax.responseType = Ajax.JSON;
          param = { 'load-cargo-submit': "Load new goods", 'city-id': cityId, 'train-id': trainId };
          ajax.ondone = function(data) {
            openCargoHolds = data.openCargoHolds;
            cargoHoldsUsed = 0;
            ajax.responseType = Ajax.FBML;
            param = { 'openCargoHolds': data.openCargoHolds, 'cityGoods': data.cityGoods, 'trainId': data.trainId };
            ajax.ondone = function(fbjsData) {
        //debugger;
              var dialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Load cargo', 'Cancel');
              dialog.onconfirm = function() {
                var goods = [];
                var goodsIds = [];
                numGoods = document.getElementById('goods-count').getValue();

                for(var i = 0; i < numGoods; i++) {
                  j = i + 1;
                  goods[i] = document.getElementById('goods-' + j).getValue();
                  goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
                }
                var trainId = document.getElementById('train-id').getValue();
                param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
                ajax.responseType = Ajax.JSON;
                ajax.ondone = function(data) {
                  loadCargo();
                }
                ajax.post(baseURL + '/turn/do-load-cargo-new', param);
                //dialog.hide();
              };
              dialog.oncancel = function() {
                loadCargo();
              }
            }
            ajax.post(baseURL + '/turn/load-cargo-new-dialog-fbjs', param);
          }
          ajax.post(baseURL + '/turn/load-cargo-select', param);
          break;
        case 'discard-existing-submit':
          ajax = new Ajax();
          ajax.responseType = Ajax.JSON;
          param = { 'load-cargo-submit': "Discard existing goods", 'city-id': cityId, 'train-id': trainId };
          ajax.ondone = function(data) {
            ajax.responseType = Ajax.FBML;
            param = { 'openCargoHolds': data.openCargoHolds, 'trainGoods': data.trainGoods, 'trainId': data.trainId };
            ajax.ondone = function(fbjsData) {
              var dialog = new Dialog().showChoice('Discard Cargo', fbjsData, 'Discard cargo', 'Cancel');
              dialog.onconfirm = function() {
                var goods = [];
                var goodsIds = [];
                numGoods = document.getElementById('goods-count').getValue();
                for(var i = 0; i < numGoods; i++) {
                  j = i + 1;
                  goods[i] = document.getElementById('goods-' + j).getValue();
                  goodsIds[i] = document.getElementById('goods-id-' + j).getValue();
                }
                var trainId = document.getElementById('train-id').getValue();
                param = { "goods": goods, "goods-id": goodsIds, "train-id": trainId };
                ajax.responseType = Ajax.JSON;
                ajax.ondone = function(data) {
                  loadCargo();
                }
                ajax.post(baseURL + '/turn/do-load-cargo-discard', param);
                //dialog.hide();
              };
              dialog.oncancel = function() {
                loadCargo();
              }
            }
            ajax.post(baseURL + '/turn/load-cargo-discard-dialog-fbjs', param);
          }
          ajax.post(baseURL + '/turn/load-cargo-select', param);
          break;
      }
      return false;
    }

Any help would be greatly appreciated. Thanks!

@Tim

I changed my loadCargo() function as follows to prevent duplication of those elements, but I am still running into the same problem as before.

var loadCargoDialog;

function loadCargo() {
  var actionPrompt = document.getElementById('action-prompt');
  actionPrompt.setTextValue('Loading cargo...');

  var ajax = new Ajax();
  ajax.responseType = Ajax.JSON;
  ajax.ondone = function(data) {
//debugger;
    ajax.responseType = Ajax.FBML;
    ajax.ondone = function(fbjsData) {
//debugger;
      if(data.loadableCargo.length == 0) {
        moveTrainManual();
      } else {
        if(loadCargoDialog == null) {
          loadCargoDialog = new Dialog().showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');

          var dlgBtnNew = document.getElementById('load-new-submit');
          dlgBtnNew.cityId = data.loadableCargo.city_id;
          dlgBtnNew.trainId = data.loadableCargo.train_id;
          dlgBtnNew.addEventListener('click', cargoEventHandler, true); //loadNewCargo);

          var dlgBtnDiscard = document.getElementById('discard-existing-submit');
          dlgBtnDiscard.cityId = data.loadableCargo.city_id;
          dlgBtnDiscard.trainId = data.loadableCargo.train_id;
          dlgBtnDiscard.addEventListener('click', discardExistingCargo, true);

        } else {
          loadCargoDialog.showChoice('Load Cargo', fbjsData, 'Minimize', 'Pass');
        }

        loadCargoDialog.onconfirm = function() {
          // Submit the form if it exists, then hide the dialog.
          loadCargoDialog.hide();
          actionPrompt = document.getElementById('action-prompt');
          actionPrompt.setInnerXHTML('<span><div id="action-text">'+
            'The "Load cargo" dialog has been minimized'+
            '</div>'+
            '<div id="action-end">'+
            '<form action="" method="POST">'+
            '<input type="button" value="Maximize" id="next-phase" onclick="loadCargo();" />'+
            '</form>'+
            '</div></span>');
          actionButton = document.getElementById('next-phase');
          actionButton.setValue('Maximize');
          actionButton.addEventListener('click', loadCargoEventHandler);
        };
        loadCargoDialog.oncancel = function() {
          moveTrainManual();
        }
      }
    }
    ajax.post(baseURL + '/turn/load-cargo-dialog-fbjs', data);
  }
  ajax.post(baseURL + '/turn/load-cargo');
}

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

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

发布评论

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

评论(1

十秒萌定你 2024-08-14 18:21:15

看起来您可能正在创建具有相同 id 的元素。那会导致它破裂。

It looks like you might be creating elements with the same id. That would cause it to break.

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