【问题标题】:jQuery selector: select a child of a known elementjQuery 选择器:选择一个已知元素的子元素
【发布时间】:2013-02-24 02:30:13
【问题描述】:

我在选择具有我知道的 ID 的特定 textarea 元素时遇到问题。 最糟糕的是,我必须处理的 HTML 页面包含两个具有此 ID 的文本区域。我知道这是不对的,但我无法控制那部分。

因此,在该页面中,我有两个主要元素:<div id="left_column"><div id="right_column">,它们都包含一个元素 <textarea id="CPR_DESCRIPTION">

在 left 和 right_columns div 及其各自的 #CPR_DESCRIPTION 子文本区域之间,还有大量其他元素,它们在每一侧都相似。

我希望分别选择这两个#CPR_DESCRIPTION textarea(因为我必须将#left_column#CPR_DESCRIPTION 的内容添加到#right_column 的内容中)但到目前为止我所有的尝试都失败了。

我试过了:

$('#left_column textarea#CPR_DESCRIPTION');

$('#left_column, textarea#CPR_DESCRIPTION');

$('#left_column').find('textarea#CPR_DESCRIPTION');

值得注意的是,我设法将#left_column 检索为一个div,但是在检索#CPR_DESCRIPTION 时,没有成功。另请注意,#CPR_DESCRIPTION 不是 #left_column 的直接子代。

这是所要求的 HTML 的相关部分(为可怕的东西做好准备):

<div id="left_column">
  <div id="property">
    <div class="body>
      <div class="inner">
        <iframe id="property">
          <html>
            <body class="dialog">
              <div id="G360Layout">
                <form id="fieldsForm">
                  <div id="mainContainer">
                    <div id="container_2">
                      <div id="fields_container">
                        <div id="container_Description">
                          <div id="component_188">
                            <table>
                              <tbody>
                                <tr>
                                  <td>
                                    <textarea id="CPR_DESCRIPTION" name="CPR_DESCRIPTION">
                                      egeezezez
                                    </textarea>
                                  </td>
                                </tr>
                              </tbody>
                            </table>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </form>
              </div>
            </body>
          </html>
        </iframe>
      </div>
    </div>
  </div>
</div>

所以这是我必须处理的怪物,你可以看到已经有重复的 ID,最糟糕的是 #right_column 完全一样。

这是我的 jQuery:

function doOnLoadLayoutDescription() {

alert("inside doOnLoadLayoutDescription");

var leftColumn = $('#left_column');
//alert("leftColumn.length="+leftColumn.length);
//var description = $('textarea#CPR_DESCRIPTION');
//var description = leftColumn.find('textarea#CPR_DESCRIPTION');
var description = $('#left_column').find('textarea[id=CPR_DESCRIPTION]');
alert("description.length="+description.length);
if(description.val()) {

    alert("inside description.val()");

    var text = description.val();

    alert(text);

    var rightColumn = $('#right_column');
    var readOnlyDescription = rightColumn .find('textarea#CPR_DESCRIPTION');
    if (readOnlyDescription.length) {

        alert("inside readOnlyDescription.length");

        readOnlyDescription.val(text);

        alert("switch done");

        }
    }
    alert("ouside doOnLoadLayoutDescription");
}

注意:我稍微改变了问题,因为我说它是一个 div 但它是一个 textarea,即使没有太大变化,现在纠正这个问题可能是个好主意。

注意 2:此 HTML 页面是从一个 .jsp 页面生成的,该页面是称为 Case360 的案例管理系统的一部分,该系统并不为人所知。由于 .jsp 的所有内容都是通过拖放式布局构建器生成的,因此它解释了为什么这个 HTML 几乎无法舒适地阅读。

编辑 我想我发现了问题: 我在那里放弃的脚本实际上被包裹在 iframe 元素内,因此只在该框架内搜索,因此找不到我的 #left_column 元素。我已经尝试将它放在 iframe 之外,以获得整个页面的范围,不仅是框架,而且我的表单的调用另一个脚本的脚本现在找不到它。为了正常工作,我需要找到一种摆脱框架的方法。我现在正在努力。

有什么想法吗?

【问题讨论】:

  • 您的第一个和第三个示例应该可以工作。你在这里得不到帮助,因为情况肯定有更多。
  • 您能否对您的 HTML 结构 + JavaScript 的相关部分制作一个 jsfiddle,然后我们会想知道到底发生了什么。
  • 您可能还遇到了 jQuery 的限制(不是错误),它只能作用于同名的单个 ID:stackoverflow.com/questions/1053882/…
  • 请发布您的 HTML。
  • .find 将像 fiddle 中看到的那样工作,因为具有相同标识符的元素不在同一级别,你没问题。其他原因导致此问题。我们需要准确的相关 HTML。如果同一个选择器中有多个相同的 id 元素会导致问题,而不是只返回第一个匹配项。

标签: jquery find selector frame parent-child


【解决方案1】:

最后,我能够完成这项工作。 因此,正如我在 EDIT 下的问题中解释的那样,主要问题是我的脚本被包裹在 &lt;iframe&gt; 元素中。 这使得使用简单的$('#CPR_DESCRIPTION') 选择第一个#CPR_DESCRIPTION textarea 变得很容易。剩下的问题是能够进入第二个&lt;iframe&gt; 找到第二个#CPR_DESCRIPTION。为了做到这一点,我奇迹般地在一个旧项目的一些黑暗地方找到了一个可以完成这项工作的函数。不过我不太了解(是的,我知道这不好)。但这是该函数的代码:

function getFrameElement(fFrames, sName) {
    var frame = null;
    var retFrameEle = null;
    var i = 0;
    for (i=(fFrames.length-1) ; i > -1 ; i--) {
        var fFrame = fFrames[i];
        if (fFrame.name == sName) {
            retFrameEle = fFrame;
            break;
        }
        if (fFrame.id == sName) {
            retFrameEle = fFrame;
            break;
        }
        retFrameEle = getFrameElement(fFrame.frames, sName);
        if (retFrameEle != null) break;
        }
    return retFrameEle;
}

我只是这样调用这个函数:getFrameElement(top.frames, "doc_content"),其中“doc_content”是我正在寻找的框架的idname

请注意,这是用基本 javascript 编写的,这意味着我需要继续使用基本 javascript 并简单地使用

getFrameElement(top.frames, "doc_content").document.getElementById("CPR_DESCRIPTION");

找到了第二个#CPR_DESCRIPTION textarea。

感谢所有帮助过的人:)

【讨论】:

    【解决方案2】:

    由于 jQuery 可能不允许重复的 ID 选择器(它不应该),试试这个:

    $('#left_column').find('textarea[id=CPR_DESCRIPTION]');
    

    【讨论】:

    • $('#left_column').find('#CPR_DESCRIPTION')$('#right_column').find('#CPR_DESCRIPTION') 工作正常jsfiddle.net/nf5j4 如果你只是做$("CPR_DESCRIPTION"),那么jQuery 只返回第一个。在前面的 2 个示例中,只有一个匹配项,因为它们位于不同的选择器中。
    • 让您的 URL 退出代码模式,以便我可以点击它。今天早上我感觉很懒。 :-)
    • 你几乎肯定是对的(在大多数情况下),但这可能值得一试。
    • 我已经尝试过了,将 div 更改为 textarea 但也不起作用,即使它应该这样做。
    • 我在您的“我尝试过”列表中没有看到这种情况。您是否使用与上述完全相同的语法(针对您的场景进行了更新)?
    【解决方案3】:

    ID 必须是唯一的,因此只需 $("#CPR_DESCRIPTION") 即可。

    但是,在一般情况下,您应该像这样使用.find()

    $(somelement).find(".selector");
    

    但是,如果您知道第一个元素的选择器,则可以使用简单的后代选择器:

    $("#someelement .selector") // any level deep
    $("#someelement>.selector") // only first-level children
    

    【讨论】:

    • 是的,这就是我在第一个示例中尝试的方法,应该可以。但由于某种原因它没有。
    • 嗯,不。即使您有重复的 ID,使用第一个选择器,您也可以缩小搜索上下文以排除具有相同 ID 的其他元素,因此它仍然可以工作。
    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    相关资源
    最近更新 更多