你能为Bootstrap指定一个“数据目标”,它指的是不使用ID的兄弟DOM元素吗?

时间:2012-10-09 18:05:31

标签: javascript twitter-bootstrap jquery-selectors

我正在动态地向页面添加可折叠元素。 Bootstrap使用"数据目标" attribute指定折叠切换应用于哪个元素。

来自文档:

The data-target attribute accepts a css selector

有没有办法编写一个指定父元素的下一个兄弟的选择器?文档中的所有示例似乎都使用ID进行选择。

具体来说,HTML看起来像:

<div class="accordion-group">
<div class="accordion-heading">
  <a class="accordion-toggle" data-toggle="collapse" data-target="#collapseOne">
    Generated Title
  </a>
</div>
<div id="collapseOne" class="accordion-body collapse in">
  <div class="accordion-inner">
    Generated Content... this is big and sometimes needs collapsing
  </div>
</div>
</div>

我想写一些像(非法使用jquery语法的伪代码):

<a class="accordion-toggle" data-toggle="collapse" data-target="$(this).parent().next()">

但我开始怀疑CSS选择器可能无法实现这一点。

现在作为一种解决方法我在创建元素时生成一个新ID(一个附加到字符串的递增数字)。

使用选择器有更好的方法吗?我应该使用一些创建后的javascript来设置数据目标属性吗?是否为标准方法生成动态内容的ID?

7 个答案:

答案 0 :(得分:26)

虽然data-target属性中的选择器确实是jQuery选择器,但此插件的data-api规范未提供在执行范围内引用回this的方法(请参阅lines 147-153 in bootstrap-collapse.js使用它。)

但是,我想提供另一种替代方法,即使用您自己的自定义切换说明符扩展data-api。我们称之为崩溃 - 下一步

JS (参见更新说明)

$('body').on('click.collapse-next.data-api', '[data-toggle=collapse-next]', function (e) {
  var $target = $(this).parent().next()
  $target.data('collapse') ? $target.collapse('toggle') : $target.collapse()
})

HTML

<a class="accordion-toggle" data-toggle="collapse-next">

JSFiddle (updated)

这里的缺点是它是一种相当紧密耦合的方法,因为JS假定了标记的特定结构。


关于IE问题的注意事项

作为@slhck pointed out in his answer,当使用我的答案的早期版本时,IE9及其显示在第一次点击时失败。原因实际上根本不是IE问题,而是Bootstrap问题。如果在.collapse('toggle')对象未初始化的目标上调用Carousel,则toggle()方法将被调用两次 - 一次在初始化期间,然后在初始化后再次显式调用。这绝对是一个Bootstrap错误,希望能得到解决。它在Chrome,FF,IE10等中没有出现的唯一原因是因为它们都支持CSS转换,因此当第二次调用时它会短路,因为第一次一个仍然活跃。上面更新的解决方法仅通过首先检查初始化并以不同方式处理它来避免双重调用问题。

答案 1 :(得分:4)

@ merv的解决方案在IE9及以下版本中对我不起作用,因为除非您单击每个项目一次,否则无法使用可折叠状态。它确实在Firefox和Chrome中运行良好。所以两次点击后,一切都会奏效。

我所做的是为触发元素设置.collapse-next类,然后强制他们的ul兄弟姐妹在toggle设置为false时崩溃:

$(".collapse-next").closest('li').each(function(){
  if ($(this).hasClass('active')) {
    // pop up active menu items
    $(this).children("ul").collapse('show');
  } else {
    // just make it collapsible but don't expand
    $(this).children("ul").collapse({ toggle: false });
  }
});

这是为了实际切换菜单状态:

$('.collapse-next').click(function(e){
  e.preventDefault();
  $(this).parent().next().collapse('toggle');
});

似乎使用data-属性是一种更现代和更清晰的方法,但对于使用类和jQuery的旧浏览器来说,似乎也可以完成这项工作。

答案 2 :(得分:2)

是的,你可以轻松完成!

只需将以下代码添加到您的脚本中即可享受:

data-mytarget

现在,代码中的每个位置都可以通过 <a data-toggle="collapse" data-mytarget="$(this).parent().next()">Link</a> 中的完全动态的jQuery命令设置崩溃目标。

现在使用它:

<a data-toggle="collapse" data-mytarget="$('#TopMenuBar').closest('ul')">Link</a>

<a data-toggle="collapse" data-mytarget="[ EACH IDEAl JQUERY CODE OF YOU STARTED WITH $( ]">Link</a>

$('body').on('click','[data-toggle="collapse"][data-mytarget^="$("]',function(){
     eval($(this).data('mytarget')).collapse('toggle');
});

<强>演示:

&#13;
&#13;
a{
  padding:10px;
  cursor:pointer;
  margin:20px;
}
&#13;
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  
  
<div class="accordion-group">
    <div class="accordion-heading">
      <a class="accordion-toggle btn btn-info" data-toggle="collapse" data-mytarget="$(this).parent().next()">Collapse It</a>
    </div>
    <div id="collapseOne" class="accordion-body collapse ">
      <div class="accordion-inner">
        Generated Content... this is big and sometimes needs collapsing
      </div>
    </div>
</div>
&#13;
data-mytarget
&#13;
&#13;
&#13;

  

我使用data-target代替data-target。如果您使用Uncaught Error: Syntax error, unrecognized expression: $(this).parent().next()它也可以,但jQuery库会引发如下错误:data-mytarget

     

所以我用 print '[+] Bruteforcing against %s with dictionary %s' % (ip, filename) for line in fd.readlines(): username, password = line.strip().split(":") t = threading.Thread(target=attempt, args=(ip,username,password)) 名称定义了我的不同属性。

答案 3 :(得分:2)

没有javascript 解决方案或者它取决于已经在使用的bootstrap js,只是利用了DOM结构 -

请参阅data-target="" ...

提示减少庞大解决方案的简便方法 -

<button
data-toggle="collapse"
data-target=".dropdown-toggle:hover + .more-menu"
type="button"
class="btn btn-primary dropdown-toggle"
>
  Toggle Bagal Wala
</button>
<div class="collapse more-menu">I will be toggled</div>

这个CSS选择结构将选择所需的DOM .dropdown-toggle:hover + .more-menu,我们可以在那里应用我们想要的CSS。 有更多方法可以利用我们拥有的东西。 :hover:active或许多其他方式。

答案 4 :(得分:1)

我认为最好的方法是迭代所有accordion-toggle个元素并通过jquery动态设置它们的data-target属性,然后在bootstrap中提到手风琴的代码。

示例:

$(function(){
    $("a.accordion-toggle").each(function(index) {
        $(this).attr("data-target", "#" + $(this).parent().next().attr("id"));
    });

    // accoridon code
});

希望这会有所帮助

答案 5 :(得分:0)

TYPO3 FCE和Bootstrap手风琴

我在这个问题上遇到了一些麻烦我也在TYPO3中为想要能够为手风琴添加无数元素的客户使用它。所以我创建了一个灵活的内容元素并映射了元素。

使用data-toggle =“collapse-next”的想法对我来说并不像我预期的那样,因为它没有关闭open元素。我创建了一个新的javascript函数,请在这里找到代码。希望有人发现这些东西很有用。

的Javascript

$(document).on('click.collapse-next.data-api', '[data-toggle=collapse-next]', function (e) {
  var $container = $(this).parents(".accordion");
  var $opencontainers = $container.find(".in");
  var $target = $(this).parent().next();
  $target.data('collapse') ? $target.collapse('toggle') : $target.collapse();
  $opencontainers.each(function() {$(this).collapse('toggle')});
})

HTML

<html>
    <div class="accordion">
        <div class="accordion-section">
            <div class="accordion-group">
                <div class="accordion-heading">
                    <a class="accordion-toggle" data-toggle="collapse-next">
                        Collapsible Group Item #1
                    </a>
                </div>
                <div class="accordion-body collapse">
                    <div class="accordion-inner">
                        Anim pariatur cliche...
                    </div>
                </div>
            </div>
        </div>
    </div>
</html>

答案 6 :(得分:0)

这是一种避免需要唯一ID并避免特定html结构的方法。

它将崩溃触发器和目标的每个实例都包含在html的“部分”中。我喜欢使用类选择器,特别是对于多个实例。在这种情况下,它避免了必须创建人工唯一ID。

借用@ merv的优秀答案,我将数据切换collapse-section命名为与他的collapse-next类似,并添加了数据部分属性。 而不是parent()。next(),这将查找最近的()节名称,然后查找给定目标名称。他们可以是兄弟姐妹或任何其他级别。

(我有一个命名约定,使用“id ...”作为用作jquery选择器的类名的前缀,以避免与样式混合。)

HTML

<div class="accordion-group idCollapseSection">
  <div class="accordion-heading">
    <a class="accordion-toggle" data-toggle="collapse-section"
       data-section=".idCollapseSection" data-target=".idCollapseTarget">
      Generated Title
    </a>
  </div>
  <div>Any other html, at various depths.
    <div class="accordion-body collapse in idCollapseTarget">
      <div class="accordion-inner">
        Generated Content... this is big and sometimes needs collapsing
      </div>
    </div>
  </div>
</div>

JS

//------------------------------
// Bootstrap Collapse.
//------------------------------
// Extend collapse to contain trigger and target within an enclosing section.
$('body').on('click.collapse-section.data-api', '[data-toggle=collapse-section]', function (e) {
  var thisTrigger = $(this);
  var sectionSelector = thisTrigger.data("section");
  var targetSelector = thisTrigger.data("target");
  var target = thisTrigger.closest(sectionSelector).find(targetSelector);
  target.data('bs.collapse') ? target.collapse('toggle') : target.collapse();
});