当屏幕处于“编辑”模式时,我想过度使用与元素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>
在页面顶部有一个Admin按钮,可以将页面置于配置模式。具有可编辑类的所有元素将处于配置模式,因此可以通过一个小形式配置元素。这个想法是屏幕上的某些控件将根据用户角色具有不同的行为。示例:如果管理员另外显示,则不显示控件。
这是通过以下方式完成的:
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函数仍然附加到事件中。如果它是一个提交函数或类似的东西,那么它也会触发不需要的东西。
我可以为原始函数设置处理程序,将其解除连接,添加新函数,然后在完成编辑后删除新函数并添加原始函数吗?
感谢您的任何提示,我希望问题很明确(可能不是)很乐意在需要时添加更多信息。
答案 0 :(得分:2)
您是否控制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 :(得分:1)
我实现这一点的方法是总是覆盖页面上每个可编辑对象的onclick处理程序,其处理程序可以简单地将调用委托给原始程序或称为管理程序版本。
你可以在dojo中轻松地连接它,如下所示:
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>
答案 2 :(得分:0)
首先让我说我恨IE,尤其是IE6。当我的公司最终离开IE6时,这将是一个美好的一天。所以我如何解决这个问题是我将一个名为oldclick的属性设置为node.onclick,然后在激活管理时设置node.onclick =“”。另一方面,我断开了hadlers并将oldclick添加回onclick。
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的帮助。如果有人想挑选我的解决方案,我就是建设性的投入游戏。