javascript - 通过链接访问页面时,Rails JavaScript 代码不执行

标签 javascript jquery html ruby-on-rails

我遇到了一个奇怪的问题...我有一个页面,它使用一些 JavaScript 在 SVG 中制作可拖动的图像,并且它可以工作。但当通过另一个页面的链接访问该页面时则不然。初始加载后重新加载页面效果很好,甚至通过 URL 栏直接访问页面也可以。我不知道该尝试什么。

在我的研究中,我偶然发现了这个答案:Rails, javascript not loading after clicking through link_to helper

但是在尝试了所有解决方案后,似乎没有一个解决方案可以解决我的问题,尽管很可能是我没有正确地将它们应用到我的代码中。我的 SVG 元素作为“onload”属性,指向“makeDraggable(evt)”函数,并且大多数解决方案都做到了这一点,因此它无法访问该函数。

这是我生成的初始链接的代码:

<%= link_to 'Play', canvas_path(:game => @game) %>

这是我的 HTML 代码:

<div id="container">
  <svg id="svg" onload="makeDraggable(evt)" width="50%" height="90%" 
  xmlns="http://www.w3.org/2000/svg">
    <defs>
      <pattern id="grid" width="40" height="40" 
       patternUnits="userSpaceOnUse">
        <rect width="80" height="80" fill="url(#smallGrid)"/>
        <path d="M 80 0 L 0 0 0 80" fill="none" stroke="black" stroke- 
        width="1"/>
      </pattern>
    </defs>
    <%@game_assets.each do |asset| %>
    <image class="draggable" id="<%=asset.id %>" height="536" width="536" 
    xlink:href="<%= url_for(asset.image) %>" x="<%= asset.position_x %>" y=" 
    <%= asset.position_y %>" style="position: relative;" 
    transform="translate(0 0)"></image>
    <% end %>
    <rect width="100%" height="100%"  style="pointer-events: none;" 
    fill="url(#grid)" />
  </svg>
</div>

这是我的 JavaScript:

$(document).on('turbolinks:load', function () {
    $('#svg').draggable();
    $('.draggable').draggable();
});

// Makes content inside of SVG draggable
// Source: http://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/
function makeDraggable(evt) {
    var svg = evt.target;

    svg.addEventListener('mousedown', startDrag);
    svg.addEventListener('mousemove', drag);
    svg.addEventListener('mouseup', endDrag);
    svg.addEventListener('mouseleave', endDrag);
    svg.addEventListener('touchstart', startDrag);
    svg.addEventListener('touchmove', drag);
    svg.addEventListener('touchend', endDrag);
    svg.addEventListener('touchleave', endDrag);
    svg.addEventListener('touchcancel', endDrag);

    var selectedElement, offset, transform,
        bbox, minX, maxX, minY, maxY, confined;

    var boundaryX1 = 10.5;
    var boundaryX2 = 30;
    var boundaryY1 = 2.2;
    var boundaryY2 = 19.2;

    function getMousePosition(evt) {
        var CTM = svg.getScreenCTM();
        if (evt.touches) { evt = evt.touches[0]; }
        return {
            x: (evt.clientX - CTM.e) / CTM.a,
            y: (evt.clientY - CTM.f) / CTM.d
        };
    }

    function startDrag(evt) {
        if (evt.target.classList.contains('draggable')) {
            selectedElement = evt.target;
            offset = getMousePosition(evt);

            console.log("started dragging")

            // Make sure the first transform on the element is a translate transform
            var transforms = selectedElement.transform.baseVal;

            if (transforms.length === 0 || transforms.getItem(0).type !== 
                SVGTransform.SVG_TRANSFORM_TRANSLATE) {
                // Create an transform that translates by (0, 0)
                var translate = svg.createSVGTransform();
                translate.setTranslate(0, 0);
                selectedElement.transform.baseVal.insertItemBefore(translate, 
              0);
            }

            // Get initial translation
            transform = transforms.getItem(0);
            offset.x -= transform.matrix.e;
            offset.y -= transform.matrix.f;

            confined = evt.target.classList.contains('confine');
            if (confined) {
                bbox = selectedElement.getBBox();
                minX = boundaryX1 - bbox.x;
                maxX = boundaryX2 - bbox.x - bbox.width;
                minY = boundaryY1 - bbox.y;
                maxY = boundaryY2 - bbox.y - bbox.height;
            }
        }
    }

    function drag(evt) {
        if (selectedElement) {
            evt.preventDefault();
            console.log("drag triggered")

            var coord = getMousePosition(evt);
            var dx = coord.x - offset.x;
            var dy = coord.y - offset.y;

            if (confined) {
                if (dx < minX) { dx = minX; }
                else if (dx > maxX) { dx = maxX; }
                if (dy < minY) { dy = minY; }
                else if (dy > maxY) { dy = maxY; }
            }

            transform.setTranslate(dx, dy);
        }
    }

    function endDrag(evt) {
        selectedElement = false;
    }
}

如果有人能够阐明正在发生的事情,我将不胜感激。

另外,如果我这篇文章的格式不太正确,请原谅我。第一次发海报:)

最佳答案

#svg 元素中删除 onload="makeDraggable(evt)",因为 当您使用 Turbolink 时,onload 函数在内联编写时将不起作用(就像 Rails 那样)。

然后将以下内容添加到您的 JS 中:

$(document).on('turbolinks:load', function () {
 if($('#svg').length == 1){
  makeDraggable($('#svg'));
 }
});

并将 var svg = evt.target; 更改为 var svg = evt;

关于javascript - 通过链接访问页面时,Rails JavaScript 代码不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56746652/

相关文章:

javascript - 如何在 JS 中不断更新来自服务器的数据?

javascript - `alert($(' table tr ').html());` 只显示一行表

javascript - Raphael JS 中的动画字体大小是否有流畅的过渡可能性?

html - 0 x 0 相对 Div 仍然占用空间

html - div 在同一行或一个在另一个之上

javascript,onclick 中的大括号不起作用?

javascript - 带有原型(prototype)的 Object.create()

javascript - 为什么我的 jQuery 事件处理程序在附加到多个元素时会失败?

javascript - 无法将文本访问到 td

html - 文本在 1cm x 1cm 单元格中居中