【问题标题】:How to pass a jQuery selector chain to my plugin?如何将 jQuery 选择器链传递给我的插件?
【发布时间】:2012-02-04 20:03:33
【问题描述】:

我对 jQuery 很陌生,我需要解决一个选择问题。我有很多带有class="trigger" 的触发器,在这些触发器上调用了jQuery 插件函数myFunc

触发器可以是图像或链接,每个触发器必须引用带有class="target"的输入字段(文本框或文本区域)。

这是一个示例,但请注意targets 可能先于跟随 triggers 最终会在between 中包含一些元素:

<a class="trigger">trigger 1</a>
<input class="target" type="text" /><!-- target for trigger 1 -->

<a class="trigger">trigger 2</a>
<textarea class="target"></textarea><!-- target for trigger 2 -->

问题是我需要将 targetSelector(如 .next('.target') 或其他取决于 DOM 的东西)传递给我的插件,以便为每个触发器获取每个目标元素:

$('.trigger').myFunc({ // Plugin invokation
   targetSelector : <code here> // Pass something like .next('.target')
});

(function($) { // Plugin defininition
    $.fn.myFunc = function(options) {

       this.each(function() { // Iterate each trigger
          var target = <code here>; // Get target for current trigger
       };

    };
})(jQuery);

【问题讨论】:

    标签: jquery jquery-plugins jquery-selectors


    【解决方案1】:

    我建议你将targetSelector 设为一个函数,其中this 指的是当前的.trigger,它会返回相应的目标:

    $('.trigger').myFunc({ // Plugin invokation
       targetSelector : function() {
           return $(this).next('.target')
       }
    });
    

    可以用.call() [docs]实现:

    $.fn.myFunc = function(options) {
    
       this.each(function() { // Iterate each trigger
          var target = options.targetSelector.call(this);
       };
    
    };
    

    这为您提供了最大的灵活性,您可以在此函数中执行您想要的任何 DOM 遍历。

    当然你可以让它更复杂,让targetSelector同时接受一个选择器字符串和一个函数,然后相应地处理这个值。

    例子:

    $.fn.myFunc = function(options) {
       var selectorFunc = $.isFunction(options.targetSelector) ? 
                             options.targetSelector :
                             function() {
                                return $(options.targetSelector);
                             };
    
       this.each(function() { // Iterate each trigger
          var target = selectorFunc.call(this);
       };
    
    };
    

    【讨论】:

    • 这只会在触发器之后找到那些,他提到目标可能在触发器元素之前,这也需要检查,.prev
    • @Patrick:只需相应地设置传递给targetSelector 的函数即可。我认为这个问题更多的是关于一般方法而不是具体情况。
    • 我喜欢你的回答并支持它。但这如何处理(非常罕见的)target1 在 trigger1 之前而 target2 在 trigger2 之后的情况?
    • @Gremo:这取决于上下文。如果两个元素 triggertarget 是其父元素中唯一具有该类的元素,则可以使用 $(this).siblings('.target') 获取 .target 兄弟,无论它是在之前还是之后。
    • 一切正常,除了您的函数(传递字符串时)可能不起作用。将“this”作为字符串传递会导致 target = document。我的意思是整个文档对象而不是触发器本身。任何想法将不胜感激!
    【解决方案2】:

    使用自定义属性而不是依赖 .next 或 .prev,因为您必须检查 prev 和 next 以查看哪个现在可以检索。

    例子

    <a class="trigger" mytarget="Target1">trigger 1</a>
    <input class="target" type="text" id="Target1" /><!-- target for trigger 1 -->
    
    <a class="trigger" mytarget="Target2">trigger 2</a>
    <textarea class="target" id="Target2"></textarea><!-- target for trigger 2 -->
    
    <script>
    $('.trigger').myFunc();
    
    (function($) { // Plugin defininition
        $.fn.myFunc = function(options) {
    
           this.each(function() { // Iterate each trigger
              var targetName = $(this).attr("mytarget");
    
              var target = $("#"+targetName); // Get target for current trigger
           };
    
        };
    })(jQuery);
    
    
    </script>
    

    【讨论】:

    • 如果你使用自定义HTML属性,你应该使用HTML5 data-*属性:ejohn.org/blog/html-5-data-attributes
    • 您不必使用 data-* html5 功能,使用它们只是为了帮助您的标记“有效”,这确实有优势但不是必需的。
    • @PatrickEvans 很好,谢谢。赞成这个想法,但我仍然希望它验证;-)
    【解决方案3】:
    $('.trigger').each(function() //split your selects
    {
        $(this).myFunc({  
            //your code here
        });    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-19
      • 2015-09-13
      相关资源
      最近更新 更多