jQuery:当 DIV 的子元素靠近其父元素的右边缘时,将 DIV 向左移动(自动滚动类型)



我目前正在构建一个有点基本的视频时间线。在此时间轴上是各种持续时间可变的媒体资产,表示资产的 DIV 的宽度反映了持续时间,1 秒的测量值为 35px。因此,例如,一个 5 秒的资产在时间轴上的宽度将占用 175px。

由于时间轴需要比页面上可用空间的宽度长,因此需要水平滚动。我没有使用丑陋的标准滚动条,而是使用 jQuery 插件滚动条,它要求时间轴的全角 DIV 位于另一个 DIV 内,该 DIV 是页面可用区域的宽度并充当框架,内部 DIV 是绝对定位的。当您向左或向右移动滚动条时,它会更改内部 DIV 的"左"值。

在给出了这个背景之后,我现在来谈谈我的问题。时间轴上的资产需要水平调整大小以调整其持续时间。我使用 jQuery UI 可以工作,但我需要这样做,以便当我将资产的右边缘拖动到框架时间轴的外部 DIV 的右边缘附近时,时间轴的内部 DIV 向左移动(基本上是滚动),资产的宽度增加 1 秒 (35px)。

即使是最后一点,我也在一定程度上工作,但还不够好。我需要的是,当我向右拖动足够远时,以便我在框架DIV右边缘的35-70像素范围内,内部DIV时间轴将向左移动,资产的宽度将增加,这种情况将一直发生,直到我将鼠标移回左侧。

我能想到的最好的例子是,当你在浏览器中选择文本并拖动到屏幕底部时,屏幕开始向下滚动,并且它会一直这样做,直到你向上移动鼠标。

目前,我正在尝试通过绘制jQuery UI可调整大小元素的"调整大小"事件来实现这一目标,但问题是我无法获得我刚刚谈论的连续效果,我必须继续将鼠标进一步向右拖动,而不仅仅是保持静止。当我到达窗口的右边缘时,我必须释放鼠标按钮,移回调整大小手柄并再次开始拖动。

这是我尝试编写的函数(仅供参考,.mediaInstance是时间轴上的资产):

//Scroll Timeline when resized handle comes close to right edge
        function timelineScroll() {
            //console.log('running');
            var mediaElement = $('#mediaTrack .mediaInstance.resizing');
            var track = $('#horiz_container_inner');
            //Determine location of right edge of the timeline viewport
            var timeline = $('#horiz_container_outer');
            var timelineOffset = timeline.offset();
            var timelineLeft = timelineOffset.left;
            var timelineRight = timelineLeft + $('#horiz_container_outer').width();
            //Find right edge of current .mediaInstance
            var instanceOffset = mediaElement.offset();
            var instanceLeft = instanceOffset.left;
            var instanceRight = instanceLeft + mediaElement.width();
            if ( (timelineRight-instanceRight) < 35 ) {
                var timelineCurrentLeft = Number(track.css('left').replace('px',''));
                var timelineNewLeft = timelineCurrentLeft - 70;
                track.css('left',timelineNewLeft);
                mediaCurrentWidth = mediaElement.width();
                mediaElement.width(mediaCurrentWidth+35);

                if (currentMousePos.x > timelineRight) {
                    while (currentMousePos.x > timelineRight) {
                        var timelineCurrentLeft = Number(track.css('left').replace('px',''));
                        var timelineNewLeft = timelineCurrentLeft - 35;
                        track.css('left',timelineNewLeft);
                        mediaCurrentWidth = mediaElement.width();
                        mediaElement.width(mediaCurrentWidth+35);
                    }
                }
            }
        }

您会注意到我什至根据鼠标位置比框架 DIV 的右边缘更右边,在那里尝试了一个循环,但我认为它不起作用,而且它没有......似乎让我陷入了一个无限循环。

无论如何,我真的很感激任何人能在这方面提供的任何帮助。我正在从事一个周转时间非常短的项目,我以前从未真正做过任何这种特殊的事情。

事实证明,我解决了自己的问题。我只需要在"调整大小"函数中使用 setTimeout,每 250 毫秒检查一次鼠标是否超出框架 DIV 的右边缘,如果是,则向左移动内部 DIV 并增加资产的宽度。这是我使用的...

编辑:事实证明,我的解决方案并没有像我希望的那样工作,所以我毕竟可以使用一些帮助。

这是 HTML:

<div id="horiz_container_outer">
    <div id="horiz_container_inner" style="position: absolute; left: 0px; top: 0px; visibility: visible;">
        <div id="horiz_container" style="width: 10500px;">

            <div id="transitionTrack"></div>
            <div id="mediaTrack" class="ui-sortable ui-droppable">
                <div class="transitionBoxContainer first ui-droppable"></div>
                <div class="mediaInstance" assetid="001" assettype="video" thumb="video1_thumb.jpg" style="display: block; width: 419px;" type="asset" duration="12">
                    <div class="mediaThumbnail" style="background-image: url(./images/assets/thumbnails/video1_thumb.jpg);"></div>
                    <div class="mediaInfo">
                        <div class="mediaFilename">video1.avi</div>
                        <div class="mediaDuration">12s</div>
                        <div class="mediaHandle"></div>
                    </div>
                    <div class="transitionBoxContainer ui-droppable"></div>
                    <div class="deleteButton"></div>
                </div>
            </div><!-- End of #mediaTrack -->
        </div><!-- End of #horiz_container -->
    </div><!-- End of #horiz_container_inner -->
</div><!-- End of #horiz_container_outer -->

这是我的代码,用于使时间轴上的mediaInstance可调整大小,捕捉为35px增量:

//Watch timeline assets for click on resize handle
$("#mediaTrack").on('mousedown','.mediaInstance .mediaHandle', function(e) {
    e.stopPropagation();
    e.preventDefault();

    //Find offset location of right edge of the timeline viewport
    var timelineViewport = $('#horiz_container_outer');
    var timelineViewportLeft = timelineViewport.offset().left;
    var timelineViewportRight = timelineViewportLeft + timelineViewport.width();
    //Assign track object to variable
    var track = $('#horiz_container_inner');
    var thisInstance = $(this).parents('.mediaInstance');
    //Store the mouse position before we start moving
    var startMousePos = e.pageX;

    $(document).mousemove(function(e){
        var currentInstanceWidth = thisInstance.width();
        //Find right edge offset of current .mediaInstance
        var instanceLeft = thisInstance.offset().left;
        var instanceRight = instanceLeft + currentInstanceWidth;

        if ( (e.pageX < (startMousePos-35)) || (e.pageX > (startMousePos+35)) ) {
            if ( e.pageX < (startMousePos-35) ) {
                thisInstance.width(currentInstanceWidth-35);
            } else { 
                                thisInstance.width(currentInstanceWidth+35);
            }
            startMousePos = e.pageX;
            recalcDuration(thisInstance);
            calcTotalDuration();
        }
    });
});
$(document).mouseup(function(e){
    $(document).unbind('mousemove');
});

这非常适合实际调整大小,但我遇到的问题是,当我将鼠标移动到 #horiz_container_outer 的右边缘(充当时间轴的框架)时,我希望 #horiz_container_inner DIV 开始以 35px 的增量将其左侧位置向左移动,同时继续调整 .mediaInstancediv 的大小以使其宽 35px......我希望这两件事每 0.25 秒发生一次......但是,我不希望 #horiz_container_inner 的"滚动"随着鼠标移动而不断触发。一旦鼠标通过 #horiz_container_outer 的右边缘,我希望某个函数接管并开始以设定的间隔滚动和调整 .mediaInstance DIV 的大小,直到鼠标再次向左移动,越过 #horiz_container_outer 的右边缘,此时上面显示的原始大小调整再次接管。

问题是我不知道如何实现这一目标。我尝试使用标志变量和条件告诉我我的鼠标何时"在区域中",首先使用 inTheZone = false,运行条件仅在 inTheZone == false 时运行我的初始代码,然后在鼠标进入正确区域后将其设置为 true,并具有 setTimeout 接管以循环滚动和调整大小。这在一定程度上有效,但是鼠标位置突然变得不可用,所以我无法分辨何时移动到区域之外,div 只是无限期地滚动。

有什么想法吗?

最新更新