JQuery Guillotine:触发多个更改事件

Posted

技术标签:

【中文标题】JQuery Guillotine:触发多个更改事件【英文标题】:JQuery Guillotine: Multiple Change Events Firing 【发布时间】:2017-02-20 16:05:48 【问题描述】:

有人可以就我在使用 JQuery Guillotine 时遇到的问题给我一些指导吗?我花了几个小时来解决这个问题,但无法确定正确的解决方案。我遇到的问题是 eventOnChange 在我更改图像后多次触发。对于每个连续的图像交换,每个事件都会触发 +1。

我研究了这个链接,但仍然无法找到可行的解决方案:jQuery Guillotine - Swap Image

我已经通过终止事件并在发布表单时捕获我需要的相关信息来解决此问题,但我无法找到可以让我利用该事件的解决方案真的很困扰。

以下是正在发生的事情的简要总结:

    使用默认用户头像加载页面 用户能够在断头台内操作头像,每次操作都会触发一个 onchange 事件(放大、缩小、旋转、适合等) 用户打开文件阅读器选择新头像 新头像已成功加载(正确缩放和尺寸) 用户操作图像,但每个操作事件触发多次。例如,在用户选择新头像后,向右旋转将旋转图像两次(180 度)。 如果用户再次打开文件阅读器,图像将触发 3 次。等等。 1 + x 次用户选择新头像...

我已经尝试在重新加载图像和初始化插件之前取消绑定事件,但它并没有解决问题。非常感谢任何帮助!

相关代码如下。

javascript

<script type="text/javascript" charset="UTF-8">
function showData (data) 
  data.scale = parseFloat(data.scale.toFixed(4))
  for(var k in data)  $('#'+k).html(data[k]) 


function loadInterface(picture) 
  showData(picture.guillotine('getData'))

  // Bind button actions
  if(!picture.data('isBound'))
    picture.data('isBound', true)
    $('#rotate_left').click(function() picture.guillotine('rotateLeft') )
    $('#rotate_right').click(function() picture.guillotine('rotateRight') )
    $('#fit').click(function() picture.guillotine('fit') )
    $('#zoom_in').click(function() picture.guillotine('zoomIn') );
    $('#zoom_out').click(function() picture.guillotine('zoomOut') )
  

  // Update data on change
  picture.on('guillotinechange', function(e, data, action)  
    console.log('guillotine onchange event called!')
    showData(data);
    console.log(action); 
  )


function loadGuillotine (picture, data) 
  if(picture.guillotine('instance')) picture.guillotine('remove') 

  // Load plugin
  picture.guillotine(
    width:  data['w'],
    height: data['h'],
    init:   data,
    eventOnChange: 'guillotinechange'
  )


$(document).ready(function() 
  var picture = $('#useravatar')
  var data    =  w: 250, h: 250, angle: 0, scale: 1 

  picture.on('load', function() 

    // Load guillotine and controls
    picture.guillotine('remove')
    loadGuillotine(picture, data)
    loadInterface(picture)

    // Transform picture to fit, center
    picture.guillotine('fit').guillotine('center')
  )
)

function ReloadImage()
  var reader = new FileReader();
  reader.readAsDataURL(document.getElementById("avatar_input").files[0]);
  reader.onload = function (oFREvent)
    document.getElementById("useravatar").src = oFREvent.target.result;
    

</script>

在 Ruby 页面内部:

<div id='content'>
  <h1>Select Avatar</h1>

  <%= form_for(@avatar, url: save_avatar_path, method: :patch) do |f| %>
  <%= render 'shared/errors', object: @avatar %>

    <div class='frame'>
      <%= image_tag 'default-user-avatar.jpg', :id => :useravatar %>
    </div>

    <div id='controls'>
      <button id='rotate_left'  type='button' title='Rotate left'> &lt; </button>
      <button id='zoom_out'     type='button' title='Zoom out'> - </button>
      <button id='fit'          type='button' title='Fit image'> [ ]  </button>
      <button id='zoom_in'      type='button' title='Zoom in'> + </button>
      <button id='rotate_right' type='button' title='Rotate right'> &gt; </button>
    </div>

    <div id='controls'>
      <%= f.hidden_field :image, value: @avatar.cached_image_data %>
      <%= f.file_field :image, :class => :form_field, :id => :avatar_input, :onChange => "ReloadImage()" %>
    </div>

    <ul id='data'>
      <div class='column'>
        <li>x: <span id='x'></span></li>
        <li>y: <span id='y'></span></li>
      </div>
      <div class='column'>
        <li>width:  <span id='w'></span></li>
        <li>height: <span id='h'></span></li>
      </div>
      <div class='column'>
        <li>scale: <span id='scale'></span></li>
        <li>angle: <span id='angle'></span></li>
      </div>
    </ul>
  <% end %>
</div>

【问题讨论】:

【参考方案1】:

我没有测试过你的代码,但是相信/猜测你掉进了一个我曾经发现自己的陷阱。

.click() 将函数事件应用于循环的每次迭代,因此为什么会触发多个更改事件(因此,如果循环调用 3 次,则事件会按顺序添加 3 次)。

尝试使用 .one() 而不是 .click()

另一个可能的解决方案是使用 .off().click() ,但它会产生开销。

【讨论】:

我认为不是点击功能。虽然事件在单击时触发多次,但在执行此行时加载图像时也会触发多次: // 将图片转换为适合,居中 picture.guillotine('fit').guillotine('center') I相信每次连续的图像更改后都会附加多个侦听器。

以上是关于JQuery Guillotine:触发多个更改事件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自 jQuery Guillotine Plugin 和 Imagick 的数据裁剪图像

jQuery 如何使 $(this) 选择器触发多个类

jquery 裁剪插件尺寸的角度指令在移动设备上已关闭

jQuery如何使$(this)选择器触发多个类

jQuery更改处理程序未触发[重复]

jQuery 自动完成触发更改事件