【问题标题】:Cloned UI Slider element causes error when dynamically added动态添加时克隆的 UI Slider 元素会导致错误
【发布时间】:2014-10-28 12:02:22
【问题描述】:

我使用以下脚本来拥有多个 jQuery UI 滑块,它们的总和是:Combined total for multiple jQuery-UI Sliders

现在我想在页面加载时从一个滑块开始,单击按钮后我想添加另一个应该包含在计算中的滑块。但不幸的是,在我的方法中,当我添加一个新滑块时,第一个滑块的值是NaN,当我尝试移动它时,我收到以下错误Uncaught TypeError: Cannot read property 'addClass' of undefined

当我从一开始就包含多个滑块时(通过 PHP),它可以正常工作。

这里是html结构:

<div class="form-group taskType">
     <label for="TaskType32" class="col-sm-4 control-label">Aufgaben Art</label>
           <div class="col-sm-8">
              <select class="form-control" id="TaskType32" name="type[]">
                  <optgroup label="DESIGN">
                      <option value="photoshop">PHOTOSHOP</option>
                      <option value="recherche">RECHERCHE</option>
                   </optgroup>
             </select>
             <div class="rangeSliderContainer">
                 <div class="slider">100</div>
                 <span class="value">100</span>%
             </div>
             <input type="hidden" class="hiddenPercentage" name="percentage[]" value="100">
        </div>
</div>

这是我的方法:

1.) 我先克隆元素

clonedTaskAdd = $('.createfinishedTask .taskType').clone();

2.) 然后我初始化滑块函数

manageSliders();

function manageSliders() {
    var sliders = $(".rangeSliderContainer .slider");
    var availableTotal = 100;

    sliders.each(function() {
        var init_value = parseInt($(this).text());

        $(this).siblings('.value').text(init_value);

        $(this).empty().slider({
            value: init_value,
            min: 0,
            max: availableTotal,
            range: "max",
            step: 2,
            animate: 0,
            slide: function(event, ui) {

                // Update display to current value
                $(this).siblings('.value').text(ui.value);
                $(this).parent().next('.hiddenPercentage').val(ui.value);

                // Get current total
                var total = 0;

                sliders.not(this).each(function() {
                    total += $(this).slider("option", "value");
                });

                // Need to do this because apparently jQ UI
                // does not update value until this event completes
                total += ui.value;

                var delta = availableTotal - total;

                // Update each slider
                sliders.not(this).each(function() {
                    var t = $(this),
                        value = t.slider("option", "value");

                    var new_value = value + (delta/2);

                    if (new_value < 0 || ui.value == 100)
                        new_value = 0;
                    if (new_value > 100)
                        new_value = 100;

                    t.siblings('.value').text(new_value);
                    t.slider('value', new_value);
                    t.parent().next('.hiddenPercentage').val(new_value);
                });
            }
        });
    });
}

3.) 在按钮单击时,我更改克隆的值并附加它

$('.createfinishedTask').on('click', '.rangeTrigger', function(e) {
        e.preventDefault();
        addSlider();
    });


function addSlider() {
    clonedTaskAdd.find('.slider, .value').text('0');
    clonedTaskAdd.find('.hiddenPercentage').val('0');
    clonedTaskAdd.find('.slider').slider();
    $('.createfinishedTask .taskType').last().after(clonedTaskAdd);
    manageSliders();
}

所以问题发生在我在addSlider() 函数中调用最后一个manageSliders(); 之后。但我不知道如何将新添加的滑块包含在总计算中。

FIDDLE

如果您需要更多信息,请随时询问。谢谢!

【问题讨论】:

  • 初步观察是您正在克隆具有 ID 的元素(例如 id="TaskType32")。 ID 在页面上必须是唯一的(jQuery 只会找到第一个)。您需要重新编写要克隆的 HTML 以适应此规则。
  • @TrueBlueAussie 感谢您的回答,但这不是问题所在。即使我删除了 ID,问题仍然存在。
  • 这只是一个观察,并不打算回答主要问题。有这么多代码,可能会出现多个问题,你真的应该把它们都放在一个 JSFiddle 中:)
  • 问:您是否为每个副本克隆克隆?否则,您最终会在随后的 after 调用中移动原始克隆元素。
  • 不,我不会为每个副本都克隆它。我只是在准备好文档时克隆它一次。问题已经从第一个动态添加的元素开始。是的,我知道很难找到有这么多代码的东西,我只是想也许这是我明显遗漏的东西。我现在没有太多时间,明天我会尝试创建一个小提琴。感谢您的努力!

标签: jquery html jquery-ui clone uislider


【解决方案1】:

问题在于初始化滑块的代码。您从现有滑块中提取了一个文本值,但该滑块的 DOM 已更改,因此您获得了一个 NAN 值。

我所做的主要更改是:http://jsfiddle.net/TrueBlueAussie/p5ty5wbv/3/

    // This value comes from the text element, but only if not converted to a slider
    if ($this.find('.ui-slider-handle').length) {
        var init_value = $this.slider("option", "value");
    } else {
        var init_value = ~~$this.text();
    }

我还更改了克隆以使用克隆的克隆,因此重用元素的问题消失了:

function addSlider() {
    var clone = clonedTaskAdd.clone();
    clone.find('.slider, .value').text('0');
    // clonedTaskAdd.find('.slider').text('0');
    clone.find('.hiddenPercentage').val('0');
    var rand = makeid();
    clone.find('label').attr('for', rand);
    clone.find('select').attr('id', rand);
    clone.find('.slider').slider();
    $('.createfinishedTask .taskType').last().after(clone);
    // $('.createfinishedTask .taskType').last().find('.slider').slider();
    manageSliders();
}

其他小的调整是我开始添加临时变量而不是重新查询元素以及使用 ~~ 而不是 parseInt(更快和更短的整数截断)。

【讨论】:

  • 非常感谢!现在它可以工作了,但不幸的是,更新的计算有时会出错。只是玩弄你的小提琴,添加更多滑块并随机移动它们并查看不同的数字,有时它们超过 100,有时低于 .. 尽管如此,我接受了你的回答,因为它回答了我原来的问题。但是,如果您有时间和空间,请随意研究一下。您似乎和我一样对 JS 有更多的经验.. ;) 再次感谢您的帮助和详细的回答。
  • 是的,看起来像整数舍入问题。你能解释一下当滑块值发生变化时分配滑块值的算法是什么?
  • 每次移动滑块时都会出现舍入误差(+/- n 其中n 是滑块的数量),因此误差会随着使用而增加。您需要限制值,但我需要先了解您的算法,然后才能提出建议:)
  • 它在manageSliders() 函数中。正如我在问题中所说,我从这个答案中得到了大部分代码:stackoverflow.com/questions/3486371/…
  • 啊......所以基本上你也不知道它是如何工作的 :) 当我有机会放松并仔细考虑时,我会进行调查。对其他人的 javascript 进行逆向工程可能会很痛苦:>
猜你喜欢
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多