2009-02-16 39 views
1

感谢三个优秀的回答,它们都确定了我使用“onclick = ...”而不是“observe(”click“,...”scriptaculous draggables:当拖动元素时需要取消onClick动作

但接受的答案该奖项已去保罗Bergantino添加类名的机制,以纪念拖动的元素,它救了我更多的工作!


在我的HTML我有一个表每行上的图像链接。

<table class="search_results"> 
    <tr> 
    <td class="thumbnail"><a href="..."><img src="..." /></a></td> 
... 

一个包含的JavaScript文件中包含的代码,使图像拖动

$$(".thumbnail a img").each(
    function(img) 
    { 
    new Draggable(img, {revert:true}); 
    } 
); 

和简单的处理来检测拖

Draggables.addObserver({ 
    onEnd:function(eventName, draggable, event) 
    { 
    // alert (eventName); // leaving this in stops IE from following the link 
    event.preventDefault(); // Does Not Work !!! 
    // event.stop(); // Does Not Work either !!! 
    } 
}); 

我的想法是,当图像被点击的结束链接应该被遵循,但是当它被拖拽时应该发生其他事情。

实际上发生的事情是,当图像被拖动时,处理程序被调用,但链接仍然被遵循。

我想我取消了错误的事件。

如何防止链接在元素被拖动后执行?


编辑:试图greystate的建议


后添加event.stop我现在有一个针对Firefox,阿帕奇等作品见下面我自己的答案碱性溶液。

但我仍在寻找一个针对IE7的解决方案(希望IE6)。

在IE中拖动图像时出现的另一个问题是,当工具提示出现时,图像与鼠标指针分离,必须释放鼠标并再次单击图像才能重新获取拖动。所以我也在寻找可能有助于解决这个问题的任何想法。

回答

1
<script> 
document.observe("dom:loaded", function() { 
    $$(".thumbnail a img").each(function(img) { 
     new Draggable(img, { 
      revert: true, 
      onEnd: function(draggable, event) { 
       $(draggable.element).up('a').addClassName('been_dragged'); 
      } 
     }); 
    }); 

    $$(".thumbnail a").each(function(a) { 
     Event.observe(a, 'click', function(event) { 
      var a = Event.findElement(event, 'a'); 
      if(a.hasClassName('been_dragged')) { 
       event.preventDefault(); 
       // or do whatever else 
      } 
     }); 
    }); 
}); 
</script> 

为我工作。它使用你的'标记'的想法,但我认为用一个类标记一个已经拖拽的元素比JavaScript变量更优雅。

0

经过一些实验后,我提出了以下修复方案。

但我不满意它,因为它似乎有点凌乱,它在IE7中不起作用。

编辑

也试过 “ev.stop” 和 “返回false” 以替代ev.preventDefault。所有给出相同的结果,在除IE以外的每个浏览器中工作。

取消注释警报证明了preventDefault即使在IE

执行

改变onEnd处理程序来处理ondrag当以避免与处理程序的调用顺序可能出现的问题。

$$(".thumbnail a img").each(
    function(img) 
    { 
    new Draggable(img, {revert:true}); 
    } 
); 

var drag_occurred = false; 
$$(".thumbnail a").each(
    function(tag) 
    { 
    tag.onclick = function(ev) 
    { 
     if (drag_occurred) 
     { 
     // alert("!"); 
     ev.preventDefault(); 
     } 
     drag_occurred = false; 
    } 
    } 
); 

Draggables.addObserver({ 
    onDrag:function(eventName, draggable, event) 
    { 
    drag_occurred = true; 
    } 
}); 
0

我现在不能测试此权利,但在我看来,你正在做的<img>拖动的,但你观察<a>元素的点击,所以这个问题也许在于点击事件气泡直到链接,它执行其默认操作。

原型有,除了防止默认操作事件stop()方法,还取消事件冒泡 - 你可以试试在onEnd功能,而不是preventDefault()

+0

感谢您的建议。我尝试在两个版本中使用Event.stop,但结果相同。第二个版本适用于大多数浏览器,但两个版本都不适用于IE。 – 2009-02-17 13:05:24

0

尝试做这个

$$(".thumbnail a").each(
    function(tag) 
    { 
    tag.onclick = function(ev) 
    { 
     if (drag_occurred) 
     { 
     ev.cancelBubble = true; 
     if (ev.stopPropagation) ev.stopPropagation(); 
     } 
     drag_occurred = false; 
    } 
    } 
); 
+0

不,不适用于IE7或Firefox(未在其他浏览器上测试) – 2009-02-23 19:25:53

1

好吧,我发现的方法是用一个“拖状态”变量,类似于以前的信息,但它的工作原理都IE7和FF下。

使用Prototype,您可以为要拖动的html元素的click事件添加一个观察者函数,并在那里告诉event.stop();。此动作扩展(即Prototype-ize)事件对象以传递给处理函数,从而丰富了所有Prototype插件方法,并使其能够调用stop()方法,而无需担心其正在运行的浏览器,因为Prototype为你管理这方面。

这里是我的例子代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
    <head> 
     <script type="text/javascript" src="lib/prototype.js"></script> 
     <script type="text/javascript" src="src/scriptaculous.js"></script> 
    <title>Draggables Test</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
    </head> 
    <body> 
    <div id="dragme"><a href="http://www.google.it">Ok, you can drag this one.</a></div> 
    <script type="text/javascript"> 
     function processIt(event) { 
      if (isDragging) { 
       event.stop(); 
      } 
      isDragging = false; 
     } 

     new Draggable('dragme', { revert: false }); 
     var isDragging = false; 

     $('dragme').observe('click', processIt); 
     Draggables.addObserver({ 
      onDrag:function(eventName, draggable, event) { 
       isDragging = true; 
      } 
     }); 
     </script> 
    </body> 
</html> 

不同的是,在你原来的例子中,你是作为一个标准的DOM事件处理的事件(见参数规格here,在页面的底部),这是可以使用FF,但IE浏览器根本不会,因为它以稍微(但绝对)不同的方式处理事件。最重要的是,您处理的事件进入您的onEnd:处理程序不是点击事件,而是事件。

在Firefox,IE
+0

+1 from me,有用答案!我看不出为什么这个投票回落。 – 2009-02-24 16:24:09

+0

现在它又回到了1 - 我很困惑 – 2009-02-24 16:29:42

+0

谢谢你,诺埃尔。我赞赏它。 – 2009-02-25 08:17:53

2
// for keeping track of the dragged anchor 
var anchorID = null; 

// register a click handler on all anchors 
$$('.thumbnail a').invoke('observe', 'click', function(e) { 
    var a = e.findElement('a'); 
    // stop the event from propagating if this anchor was dragged 
    if (a.id == anchorID) { 
     e.stop(); 
     anchorID = null; 
    } 
}); 

$$('.thumbnail a img').each(function(img) { 
    new Draggable(img, { revert:true }); 
}); 

Draggables.addObserver({ 
    onStart: function(eventName, draggable, e) { 
     // store the dragged anchor 
     anchorID = e.findElement('a').id; 
    } 
}); 
相关问题