1

感谢三个出色的答案,它们都确定了我使用“onclick = ...”而不是“observe(“click”,...”)的问题

但是,Accepted Answer 的奖项必须授予 Paolo 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 !!!
  }
});

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

事实上,当图像被拖动时,处理程序被调用,但链接仍然被跟踪。

我想我取消了错误的活动。

拖动元素后如何防止链接被跟踪?


编辑:event.stop在尝试了 graystate 的建议后添加


我现在有一个适用于 FireFox、Apache 等的基本解决方案。请参阅下面我自己的答案。

但我仍在寻找 IE7(希望是 IE6)的解决方案。

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

4

6 回答 6

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;
    }
});
于 2009-02-24T11:40:13.833 回答
1

好的,我发现的方式是使用“拖动状态”变量,类似于您之前的帖子,但它适用于 IE7 和 FF。

使用 Prototype,您可以为要拖动的 html 元素的 click 事件添加一个观察者函数,告诉 in there event.stop();。此操作扩展(即原型化)要传递给处理函数的事件对象,从而丰富它的所有 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 事件(请参阅此处的参数规范,页面底部),这对于 FF 是可以的,但对于 IE 则完全不行,因为它处理事件稍微(但绝对)不同的方式。最重要的是,您在处理程序中处理的onEnd:事件不是单击事件,而是onend事件。

于 2009-02-24T11:30:04.407 回答
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>

在 Firefox、IE 上为我工作。它有点使用你的“标记”想法,但我认为用类标记已经拖动的元素比 javascript 变量更优雅。

于 2009-02-24T12:18:51.510 回答
0

经过一些实验,我想出了以下修复方法。

但我对它不太满意,因为它看起来有点乱,而且在 IE7 中不起作用。

编辑

还尝试了“ev.stop”和“return false”作为 ev.preventDefault 的替代方案。所有都给出相同的结果,在除 IE 之外的所有浏览器中工作。

取消注释警报证明即使在 IE 中也正在执行 preventDefault

将 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;
  }
});
于 2009-02-16T11:07:35.943 回答
0

我现在无法对此进行测试,但正如我所见,您正在制作<img>可拖动的元素,但您正在观察<a>元素上的点击,所以问题可能是点击事件冒泡到执行其默认值的链接行动。

Prototype 有一个stop()事件方法,除了阻止默认操作外,还取消事件冒泡 - 你可以在 onEnd 函数中尝试,而不是preventDefault().

于 2009-02-17T08:00:58.007 回答
0

尝试这样做

$$( ".thumbnail a" ).each(
  function( tag )
  {
    tag.onclick = function( ev )
    {
      if ( drag_occurred )
      {
        ev.cancelBubble = true;
        if (ev.stopPropagation) ev.stopPropagation();
      }
      drag_occurred = false;
    }
  }
);
于 2009-02-23T18:39:57.857 回答