Может ли dojo получить доступ к функции, связанной с элементами HTML Event? - PullRequest
0 голосов
/ 26 октября 2009

Я бы хотел перегрузить функцию, связанную с событием onclick элементов, когда экран находится в режиме «редактирования». Затем, когда закончите редактирование, верните исходную функцию обратно.

Итак, изначально у меня есть следующее:

<script type="text/javascript">
    var showAddNewForum = function(){
        dojo.byId("NewForum").className = dojo.byId("NewForum").className == 'hidden'?'':'hidden';
    }
</script>
<a  onclick="showAddNewForum()" class="editable" id="AddNewForum" name="AddNewForum" style="cursor:pointer;">New Forum</a>
        <div class="hidden" id="NewForum" name="NewForum">
            <form action="">
                <table>
                    <tr><td><label>Title</label></td><td><input type="text" id="newForumTitle"/></td></tr>
                    <tr><td><label>Description</label></td><td><input type="text" id="newForumDescription"/></td></tr>
                    <tr><td><label>Moderators</label></td><td><input type="text" id="newForumnModerators"/></td></tr>
                </table>
                <input type="button" value="submit"/>
            </form>
        </div>

В верхней части страницы есть кнопка администратора, которая переведет страницу в режим настройки. Все элементы с классом editable будут в режиме конфигурации, поэтому элемент можно настроить с помощью небольшой формы. Идея заключается в том, что определенные элементы управления на экране будут иметь различное поведение в зависимости от роли пользователя. Пример: если администратор показывает это по-другому, не отображать элемент управления.

Это делается с помощью следующего:

    activateAdministration = function() {
        if (editOnClickHandle.length>0) {
            dojo.forEach(editOnClickHandle,function(item){dojo.disconnect(item)});
            editOnClickHandle = [];
        }else {
            dojo.query(".editable").forEach(function(node,idx,arr){
                var handler = dojo.connect(node,"onclick",function(e){
                    console.debug(node.onclick);
                    var adminWindow = document.getElementById("adminWindow");
                    adminWindow.className = "displayInline";
                    adminWindow.style.top = (e.layerY + 0) + "px";
                    adminWindow.style.left = (e.layerX + 0) + "px";
                    document.getElementById("adminElementId").value = node.id;
                    document.getElementById("adminCurrentUrl").value = location.href;
                    document.getElementById("adminClass").value = node.className;
                });
                editOnClickHandle.push(handler);
            });
        }
    }
<a class="tool" style="cursor:pointer;" onclick="activateAdministration();">Admin</a>

Таким образом, проблема в том, что оригинальная функция onclick все еще прикреплена к событию. Если бы это была функция отправки или что-то в этом роде, она также сработала бы, что нежелательно.

Могу ли я установить обработчик для исходной функции, отсоединить его, добавить новую функцию, а затем по завершении редактирования удалить новую функцию и добавить исходную обратно?

Спасибо за любые советы, я надеюсь, что вопрос ясен (вероятно, нет), рад добавить дополнительную информацию, если это необходимо.

Ответы [ 3 ]

2 голосов
/ 27 октября 2009

Контролируете ли вы код для функции showAddNewForum () и ее вставку в HTML? В этом случае я бы, вероятно, просто использовал один обработчик, например:

dojo.connect(dojo.byId("AddNewForum"), "onclick", function(evt) {
    if (dojo.hasClass(evt.target, "editable") {
        //do the editing work here
        doConfiguration(evt.target);
    } else {
        //do regular work here.
        doRegularAction(evt.target);
    }
});

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

1 голос
/ 30 октября 2009

Я бы реализовал это так: всегда переопределяет обработчик onclick для каждого редактируемого объекта на странице с помощью обработчика, который либо просто делегирует вызов оригиналу, либо вызывает версию администратора.

Вы можете легко подключить это в додзё, например:

  admin_mode = false;
  activateAdministration = function() {
    admin_mode = true;
  };

  editClick = function(e) {
    console.debug("..in admin edit function; this=%o; e=%o", this, e);
    // do your admin stuff here
    // var node = this;
  };

  dojo.query('.editable').forEach(function(node) {

    if (node.onclick) {
      var original_onclick = node.onclick;
      node.onclick = function() {
        if (admin_mode) {
          console.debug("calling admin onclick handler");
          editClick.apply(node, arguments);
        } else {
          // delegate
          console.debug("calling original onclick handler");
          original_onclick.apply(node, arguments);
        }
      }
    }

  });

Я проверил это с помощью HTML следующим образом:

<a onclick="console.debug('I am the original!; this=%o; args=%o', this, arguments);" 
   class="editable"> 
  EDITABLE 
</a>

<a onclick="console.debug('Me too!; this=%o; args=%o', this, arguments);" 
   class="editable"> 
  ALSO EDITABLE 
</a>
0 голосов
/ 27 октября 2009

Прежде всего позвольте мне сказать, что я ненавижу IE, особенно IE6. Это будет действительно хороший день, когда моя компания, наконец, уйдет с IE6. Итак, как мне это удалось - я установил атрибут с именем oldclick для node.onclick, а затем установил node.onclick = "" при активации Administration. С другой стороны я отсоединяю хэдлеры и добавляю oldclick обратно к онклику.

var editOnClickHandle = []; 
activateAdministration = function() {
        if (editOnClickHandle.length>0) {//turn off administration
            dojo.forEach(editOnClickHandle,function(item){dojo.disconnect(item)});
            dojo.query(".editable").forEach(function(node,idx,arr){
                if(dojo.isIE){
                    node.onclick=node.getAttribute("oldclick");
                }else{
                    node.onclick=dojo.hitch(node.onclick,node.getAttribute("oldclick"));
                }               
            });
            editOnClickHandle = [];
        }else {//turn on administration
            dojo.query(".editable").forEach(function(node,idx,arr){
                var onClickName = new String(node.getAttribute("onclick"));
                var oldClickName = onClickName.substring(0,onClickName.indexOf("("));
                if(dojo.isIE){
                    node.setAttribute("oldclick",node.onclick);
                }else{
                    node.setAttribute("oldclick",oldClickName);
                }
                node.onclick="";
                editOnClickHandle.push(dojo.connect(node,"onclick",editClick));
            });
        }
    }

Не относится к этой проблеме, но для ясности я преобразовал небольшой код окна администратора в отдельную функцию editClick. Похоже:

editClick = function(e){
    console.debug(e);
    var adminWindow = document.getElementById("adminWindow");
    adminWindow.className = "displayInline";
    adminWindow.style.top = (e.layerY + 0) + "px";
    adminWindow.style.left = (e.layerX + 0) + "px";
    document.getElementById("adminElementId").value = e.target.id;
    document.getElementById("adminCurrentUrl").value = location.href;
    document.getElementById("adminClass").value = e.target.className;
}

Так что, надеюсь, это поможет кому-то в будущем, спасибо за вашу помощь, jrburke. Если кто-то хочет разобрать мое решение, я играю для конструктивного ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...