JQuery断头台:多变化事件发生

时间:2017-02-20 16:05:49

标签: javascript jquery

有人可以给我一些指导,解决我遇到的JQuery Guillotine问题吗?我花了几个小时研究这个问题并且找不到正确的解决方案。我遇到的问题是在更改图像后eventOnChange多次触发。每次连续图像交换都会触发+1事件。

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

我通过杀死事件并在发布表单时捕获我需要的相关信息来解决这个问题,但是我真的很难找到一个能够让我利用这个事件的解决方案。 / p>

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

  1. 页面加载默认用户头像
  2. 用户能够操纵断头台内的头像,并且每次操作都会触发一个onchange事件(放大,缩小,旋转,适合等)。
  3. 用户打开文件阅读器以选择新的头像
  4. 新头像已成功加载(正确缩放和尺寸)
  5. 用户操纵图像但每次操作事件都会多次触发。例如,向右旋转将在用户选择新头像后将图像旋转两次(180度)。
  6. 如果用户再次打开文件阅读器,图像将触发三次。一个人。用户选择新头像的1 + x倍......
  7. 我在重新加载图片和初始化插件之前尝试解除绑定事件,但它还没有解决问题。非常感谢任何帮助!

    相关代码如下。

    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 Page:

    <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 个答案:

答案 0 :(得分:0)

我没有测试过您的代码,但相信/猜测您已陷入我曾经发现的陷阱。

.click()在循环的每次迭代中都会应用你的函数事件,这就是为什么你会激活多个更改事件(因此如果循环调用三次,那么事件将按顺序添加三次)。

尝试使用。one()代替.click()

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