CSS - 父子选择器不起作用

时间:2016-03-15 15:46:14

标签: javascript jquery html css

我有以下代码:

.recipe
  .ingredients
    = f.simple_fields_for :ingredients do |ingredient|
      = render 'ingredient_fields', f: ingredient
  .row#links
    .col-xs-12
      = link_to_add_association "", f, :ingredients
  %hr

我需要使用jquery选择成分div,格式为$("#links")["closest"](".recipe > .ingredients"),但这并不能选择任何内容。

虽然$("#links")["closest"](".recipe > .row")将返回正确的div,但令人沮丧。

无效的小提琴:https://jsfiddle.net/yL6dr4s1/

4 个答案:

答案 0 :(得分:2)

根据jQuery文档,closest方法尝试通过测试元素本身来查找匹配选择器的元素 遍历DOM

它没有通过元素的兄弟姐妹。

根据您的要求,您似乎想要遍历树以获得兄弟姐妹的匹配。 jQuery有siblings方法来做到这一点。因此,一种解决方案是使用兄弟姐妹方法,如:

$("#links")["siblings"](".recipe > .ingredients")

另一个倾向是获得最亲近的父母,然后使用@mhodges

回答的孩子

至于查询$("#links")["closest"](".recipe > .row"):

它工作正常,因为最接近的方法在元素本身中找到匹配。

以下是展示:

的示例

$(document).ready(function() {
  // Match found because it is parent
  console.log($("#links")["closest"](".wrapper").length);
  // No match found because element is sibling
  console.log($("#links")["closest"](".row1").length);
  // No match found because element is sibling
  console.log($("#links")["closest"](".row3").length);
  // Match found because it is element itself
  console.log($("#links")["closest"](".row2").length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="row1">
    <span>Content1</span>
  </div>
  <div class="row2" id="links">
    <span>Content2</span>
  </div>
  <div class="row3">
    <span>Content3</span>
  </div>
</div>

答案 1 :(得分:1)

我不确定您使用所提供的确切选择器/语法的要求,但此选择器的工作方式与您的完全一致。

function sendEmailWithPdf() {
    var 
   source   = SpreadsheetApp.getActiveSpreadsheet(),
    subject = source.getSheets()[1].getRange('b2').getValue(),
       body = source.getSheets()[1].getRange('b3').getValue(),
        pdfName = 'Training Workout',
  source = SpreadsheetApp.getActiveSpreadsheet(),
        sheetName = source.getActiveSheet().getName(),
        mailTo = source.getActiveSheet().getRange('g2')
            .getValue(),
        url,
        sheets = source.getSheets()
        sheets.forEach(function (s, i) {
            if (s.getName() !== sheetName) s.hideSheet();
        });
    url = Drive.Files.get(source.getId())
          .exportLinks['application/pdf'];
    url = url + '&size=letter' + //paper size
    '&portrait=false' + //orientation, false for landscape
    '&fitw=true' + //fit to width, false for actual size
    '&sheetnames=false&printtitle=false&pagenumbers=false' + //hide optional
    '&gridlines=false' + //false = hide gridlines
    '&fzr=false'; //do not repeat row headers (frozen rows) on each page
    var token = ScriptApp.getOAuthToken();
    var response = UrlFetchApp.fetch(url, {
        headers: {
            'Authorization': 'Bearer ' + token
        }
    });

    MailApp.sendEmail(mailTo, subject, body, {
        attachments: [response.getBlob().setName(pdfName)]
    });
    sheets.forEach(function (s) {
        s.showSheet();
    })

}

修改

这是我能得到的最接近的:

$(this).closest(".recipe").children(".ingredients").append('<br/><input type="text" value="Flour">');

答案 2 :(得分:0)

我认为你不能按照你提出的方式使用选择器。

就DOM而言(和jQuery),ingredient定义的元素和row定义的元素不相关。你必须遍历到父元素,然后返回以找到孩子。

Here is a fiddle希望能够证明这个问题。

如果您可以更改它,以便ingredientrow都在同一个父div中,那么您的测试选择器语法可能会更加幸运。

答案 3 :(得分:0)

当jQuery遇到错误,没有某个选项或者只是变得混乱使用某个操作时,我们也可以访问旧的普通javascript。

document.querySelector('#addToIngredients').addEventListener('click' , function(e) {

  var recipe = getClosest(e.target,'recipe');  
  if (recipe) {
    var ingred = recipe.querySelector('.ingredients');
    ingred.innerHTML += '<br/><input type="text" value="Flour">';
  }
  
});

function getClosest(elem,cls) {
  var el = elem.parentNode;
  while (el){
    if (el.className.indexOf(cls) > -1) {
      return el;
    }
    el = el.parentNode;
  }
  return false;
}
<div class="recipe">
  <div class="ingredients">
    <input type="text" value="Eggs"><br/>
    <input type="text" value="Flour">
  </div>
  <div class="row">
    <div class="col-xs-12">
      <a href="#" id="addToIngredients">Add to .ingredients</a>
    </div>
  </div>
  <hr/>
</div>

当然可以合并

$(function() {
    $("#addToIngredients").on('click', function(e) {
      var recipe = getClosest(e.target,'recipe');  
      if (recipe) {
        var ingred = recipe.querySelector('.ingredients');
        ingred.innerHTML += '<br/><input type="text" value="Flour">';
      }
  });
})
相关问题