2

假设我的总宽度为 585px。我想将空间分成相等的部分,并在位置内为每个部分分配一个索引值。如果我说 6 个部分,我可以做这样的事情:(按总宽度/部分数分配)

    //Set up elements with variables
            this.sliderContent = config.sliderContent;
            this.sectionsWrap = config.sectionsWrap;

            //Selects <a>
            this.sectionsLinks = this.sectionsWrap.children().children();

            //Create drag handle
            this.sectionsWrap.parent().append($(document.createElement("div")).addClass("handle-containment")
                                      .append($(document.createElement("a")).addClass("handle ui-corner-all").text("DRAG")));

            //Select handle
            this.sliderHandle = $(".handle");

var left = ui.position.left,
    position = [];

var position = ((left >= 0 && left <= 80) ? [0, 1] :
    ((left >= 81 && left <= 198) ? [117, 2] :
    ((left >= 199 && left <= 315) ? [234, 3] :
    ((left >= 316 && left <= 430) ? [351, 4] :
    ((left >= 431 && left <= 548) ? [468, 5] :
    ((left >= 549) ? [585, 6] : [] ) ) ) ) ) );

        if (position.length) {
            $(".handle").animate({
                left : position[0]
            }, 400);
            Slider.contentTransitions(position);
        }

但是,如果我有 x 个部分怎么办。这些部分只是像

<li><a></a></li>
<li><a></a></li>
<li><a></a></li>

或者

<div><a></a></div>
<div><a></a></div>
<div><a></a></div>
<div><a></a></div>

我将如何划分 585px 的总数并根据.handle元素的当前左值对位置的索引进行分类?我可以通过使用知道拖动手柄的位置ui.position.left,我想要的是能够为每个元素设置一个索引,并能够根据手柄在索引元素中的位置为手柄设置动画。由于每个元素都有索引,我稍后调用一个转换方法并传入当前索引 # 以显示。我上面显示的代码有效,但效率不高。我还需要考虑手柄的宽度以适应截面宽度。http://jsfiddle.net/yfqhV/1/

我做的例子

4

3 回答 3

1
var numSections = // ...;
var totalWidth = // ...;
var sectionWidth = totalWidth / numSections;
var index = Math.floor($(".handle").position().left / sectionWidth);
var leftPosition = index * sectionWidth;
var rightPosition = leftPosition + sectionWidth - 1;
于 2013-03-05T17:36:47.520 回答
1

好的,问题中的范围数字之间的差异略有不一致,这使得算法很难准确地 [my made-up-word de jour =)]:

  • 81 到 199 = 118
  • 199 到 316 = 117
  • 316 到 431 = 115
  • 431 到 518 = 118

如果您可以对此进行调整,我有一个解决方案 - 它不是特别聪明的 JavaScript,因此可能有更好的方法来做到这一点(SO JS 人,请随时教育我!)但它确实有效。

首先,我们需要一个函数来查找数组范围的索引,给定的值落在其中(这将替换嵌套的 if-else 简写),然后我们有一个函数来设置位置数组,最后我们可以进行范围搜索并返回相应的值数组。

此解决方案应动态处理不同数量的部分,只要此行:

var len = $("#sectionContainer").children().length;

作相应调整。可能需要调整的唯一其他值是:

    var totalWidth = 585;
    var xPos = 81;

尽管如果您有可以从中提取值的元素,则可以设置它们,使其更像是一种动态解决方案。

/**
 * function to find the index of an array element where a given value falls
 * between the range of values defined by array[index] and array[index+1]
 */
function findInRangeArray(arr, val){
  for (var n = 0; n < arr.length-1; n++){

      if ((val >= arr[n]) && (val < (arr[n+1]))) {
          break;
      }
  }
  return n;
}

/**
 * function to set up arrays containing positional values
 */
function initPositionArrays() {
    posArray = [];
    leftPosArray = [];

    var totalWidth = 585;
    var xPos = 81;

    var len = $("#sectionContainer").children().length;
    var unit = totalWidth/(len - 1);

    for (var i=1; i<=len; i++) {
      pos = unit*(i-1);
      posArray.push([Math.round(pos), i]);
      xMin = (i >= 2 ? (i==2 ? xPos : leftPosArray[i-2] + posArray[1][0]) : 0);
      leftPosArray.push(Math.round(xMin));
    }
}

var left = ui.position.left;

initPositionArrays();

// find which index of "leftPosArray" range that "left" falls within
foundPos = findInRangeArray(leftPosArray, left);
var position = posArray[foundPos];

if (position.length) {
  $(".handle").animate({
    left : position[0]
  }, 400);
  Slider.contentTransitions(position);
}

我已经设置了一个jsFiddle来说明。

享受!


编辑

我查看了@JonnySooter 自己的答案,虽然它正确计算了定位,但它不会处理可变数量的部分。

为了让它与任意数量的部分一起工作,handleContainmentdiv(即动态创建)需要动态设置它的宽度(通过内联样式)。
这是通过将节数乘以每个节的宽度(实际上与滑块的宽度相同)来计算的。
这一切都是在创建句柄之后完成的,以便可以从“句柄”css 类中提取宽度,这意味着当在 css 级别应用时,对句柄宽度的更改将级联到例程中。

请参阅此jsFiddle,其中可以更改部分的数量并且滑块的行为正常。

于 2013-03-06T11:58:29.890 回答
0

更新

我努力自己寻找解决方案,这就是我想出的:

function( event, ui ) {
    var left = ui.position.left, //Get the current position of the handle
        self = Slider, //Set to the Slider object cus func is a callback
        position = 1;
        sections_count = self.sectionsLinks.length, //Count the sections
        section_position = Math.floor(self.sectionsWrap.width() / sections_count); //Set width of each section according to total width and section count

    left = Math.round(left / section_position); //Set the index
    position = (left * section_position); //Set the left ammount

    if(position < section_position){ //If handle is dropped in the first section
        position = 0.1; //Set the distance to animate
        left = 0; //Set index to first section
    }

    if (position.length) {
        $(this).animate({
            left : position //Animate according to distance
        }, 200);
        left = left += 1; //Add one to the index so that I can use the nth() child selector later.
        self.contentTransitions(left);
    }
}
于 2013-03-07T15:32:57.570 回答