如何将 jQuery UI 滑块委托给 DOM?

Posted

技术标签:

【中文标题】如何将 jQuery UI 滑块委托给 DOM?【英文标题】:How do I delegate a jQuery UI slider to the DOM? 【发布时间】:2020-11-19 09:42:04 【问题描述】:

我有这个使用 jQuery UI API 的 range 滑块,它按预期工作,但现在我试图将滑块委托给 DOM,无论我尝试什么它都不起作用.这是我的初始代码(没有选择器委托):

html [初始]

<div class="SliderContainer">
                    
    <input type="hidden" id="minWT" value="2.5" />
    <input type="hidden" id="maxWT" value="30" />

    <p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>

    <div class="rangeContainer">
        <div id="WTrange"></div>
    </div>

</div>

JS [初始]

$('#WTrange').slider(
        
    range: true,
    values: [2.50, 30.00],
    min: 2.50,
    max: 30.00,
    step: 0.01,
    change:

        function(event, ui) 
            
            alert('Things have changed!');
            
        ,
    slide: 

        function(event, ui) 
            
            // Prevent range thumbs from overlapping
            if ((ui.values - ui.values[1]) < 3) 

                return false;

            
        
            $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
            $('#minWT').val(ui.values[0]);
            $('#maxWT').val(ui.values[1]);
            
        
        
);

在谷歌搜索后,我找到了this potential solution。但是我要么做错了,要么因为我似乎无法正确处理而无法正常工作:

JS 尝试 1 失败

$('#WTrange').slider();

$(document).on('slidecreate', '#WTrange', function(event, ui) 

).on('slider', '#WTrange', function(event, ui) 

    range: true,
    values: [2.50, 30.00],
    min: 2.50,
    max: 30.00,
    step: 0.01
        
).on('slidechange', '#WTrange', function(event, ui) 

    alert('Things have changed!');
  
).on('slide', '#WTrange', function(event, ui) 

  // Prevent range thumbs from overlapping
  if ((ui.values - ui.values[1]) < 3) 

      return false;

  

    $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
    $('#minWT').val(ui.values[0]);
    $('#maxWT').val(ui.values[1]);

);

当running this (in JSFiddle) 我得到这个错误:

"<a class='gotoLine' href='#35:9'>35:9</a> Uncaught SyntaxError: Unexpected token ':'"
The jQuery UI Slider Widget API manual that I've been referencing to do this

有人知道将这个 jQuery UI 滑块小部件委托给 DOM 的正确方法吗?


编辑 1

我尝试将其重新格式化为委托,但仍然无效:

JS 尝试 2 失败


$('#WTrange').slider();
$(document).on('slide', '#WTrange', 'option', 'range', true);
$(document).on('slide', '#WTrange', 'option', 'values' [2.50, 30.00]);
$(document).on('slide', '#WTrange', 'option', 'min', 2.50);
$(document).on('slide', '#WTrange', 'option', 'max', 30.00);
$(document).on('slide', '#WTrange', 'option', 'step', 0.01);
$(document).on('slidechange', '#WTrange', function(event, ui) 

    alert('Things have changed!');

);

$(document).on('slide', '#WTrange', function(event, ui) 

    // Prevent range thumbs from overlapping
    if ((ui.values - ui.values[1]) < 3) 
    
        return false;
    
    
    
    $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
    $('#minWT').val(ui.values[0]);
    $('#maxWT').val(ui.values[1]);

);

编辑 2

有人告诉我我的问题不够清楚。这是more minimal and reproducible example:

$(document).ready() 上的 HTML

<div id="pageContent">
    <button>Show Slider</button>
</div>

注意: jQuery UI 滑块没有 HTML

$(document).ready() 上的 JS

$('button').on('click', function() 
    $('#pageContent').load('sliderPage.php');
);

$('#WTrange').slider(

    range: true,
    values: [2.50, 30.00],
    min: 2.50,
    max: 30.00,
    step: 0.01,
    change:

        function(event, ui) 

            alert('Things have changed!');

        ,
    slide: 

        function(event, ui) 

            // Prevent range thumbs from overlapping
            if ((ui.values - ui.values[1]) < 3) 

                return false;

            

            $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct'); // Show value above range slider
            $('#minWT').val(ui.values[0]);
            $('#maxWT').val(ui.values[1]);

        

);

注意:当用户.click()s 时&lt;button&gt;sliderPage.php 将.load()

sliderPage.php 加载后的HTML &lt;button&gt;点击

<div id="pageContent">
    <div class="SliderContainer">

        <input type="hidden" id="minWT" value="2.5" />
        <input type="hidden" id="maxWT" value="30" />
    
        <p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>
    
        <div class="rangeContainer">
            <div id="WTrange"></div>
        </div>

    </div>
</div>

注意:现在同一页面上有 jQuery UI 滑块的 HTML


基本问题: 因为&lt;div class="SliderContainer"&gt; 的HTML 内容不是$(document).ready() 上DOM 的一部分,所以它们的事件必须是.delegate()d 在DOM 树上。如何委托这个 jQuery UI 滑块以便我的 JS 识别它?

【问题讨论】:

slider 是一个插件,而不是一个事件。您很可能无法委派它。 您是否知道在.load()父选择器之后除了委派它之外还有其他方法可以显示它吗? 您可以在需要/可用的时间点初始化它。 对不起,我对此有点陌生; 初始化是什么意思? $('#WTrange').slider( slider() 的调用正在“初始化”插件逻辑。这是设置步骤。 【参考方案1】:

请查看:https://api.jqueryui.com/slider/

这是一个如何使用它的示例。

$(function() 
  $('#WTrange').slider(
    range: true,
    values: [2.50, 30.00],
    min: 2.50,
    max: 30.00,
    step: 0.01
  ).on("slidechange", function(event, ui) 
    alert('Things have changed!');
  ).on("slide", function(event, ui) 
    if ((ui.values - ui.values[1]) < 3) 
      return false;
    
    $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct');
    $('#minWT').val(ui.values[0]);
    $('#maxWT').val(ui.values[1]);
  );
);
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="SliderContainer">
  <input type="hidden" id="minWT" value="2.5" />
  <input type="hidden" id="maxWT" value="30" />
  <p class="wtNumber" id="showWT">2.5Ct - 30Ct</p>
  <div class="rangeContainer">
    <div id="WTrange"></div>
  </div>
</div>

更新

正如您在编辑中所述,您正在使用.load() 提取所需的 HTML,然后使用 jQuery UI 滑块对其进行初始化。我会使用.load() 的完整回调功能。查看更多:https://api.jquery.com/load/

类型:Function(String responseText, String textStatus, jqXHR jqXHR) 请求完成时执行的回调函数。

$('button').on('click', function() 
  $('#pageContent').load('sliderPage.php', function()
    $('#WTrange').slider(
      range: true,
      values: [2.50, 30.00],
      min: 2.50,
      max: 30.00,
      step: 0.01,
      slide: function(event, ui) 
        if ((ui.values - ui.values[1]) < 3) 
          return false;
        
        $('#showWT').html(ui.values[0] + 'Ct - ' + ui.values[1] + 'Ct');
        $('#minWT').val(ui.values[0]);
        $('#maxWT').val(ui.values[1]);
      ,
      change: function(event, ui) 
        alert('Things have changed!');
      
    );
  );
);

现在元素将存在并且事件将成功绑定。你不需要委托。问题的症结在于您不能委托.slider() 的初始化。您可以委托 changeslide 事件,但不能委托最初的 .slider() 调用,因为它不是事件。

更新 2

由于您的内容无法被其他人测试,我在 JSFiddnle 中创建了一个伪测试:https://jsfiddle.net/Twisty/zjeLdmw5/8/

这会将 HTML 回显到 .load() 函数,其方式与您的页面加载内容的方式相同。当我点击按钮时,内容被替换为 HTML,然后 Slider 被初始化。

这显示了我建议的代码有效。您的代码可能还有其他一些尚不清楚的问题。

【讨论】:

评论不用于扩展讨论;这个对话是moved to chat。

以上是关于如何将 jQuery UI 滑块委托给 DOM?的主要内容,如果未能解决你的问题,请参考以下文章

Jquery ui 1.8.10 范围滑块不适用于 jquery 3.4.1

如何限制 jQuery UI 滑块的范围?

使用英寸的 jquery ui 滑块

如何防止多个句柄在 jQuery UI 滑块中重叠?

如何阻止jquery UI滑块滑动到排水沟之外?

如何将 jQuery UI 控件转换为表单元素契约?