【问题标题】:Javascript: How to tell if a span is the first thing in a paragraph?Javascript:如何判断跨度是否是段落中的第一件事?
【发布时间】:2016-01-21 07:38:03
【问题描述】:

我是一名客观的 C 程序员,我在最近的项目中需要一些 Javascript。一周前,我从未使用过任何 javascript。我在这个特殊问题上花了几个小时,但无法弄清楚。我对javascript几乎一无所知,所以如果我犯了任何基本错误(很可能),我提前道歉。

基本上我有一个 html 页面。页面中有许多自定义跨度标签。我需要一个函数来告诉我任何特定的跨度标记是否是段落中的第一件事(不仅仅是第一个跨度)。例如如果 html 看起来像这样:

<p><span class="myClass">The</span> quick brown fox jumps over the lazy <span class="myClass">dog.</span></p>

然后我用

var spanList = Document.getElementsByClassName("myClass");

我需要一个为

返回 TRUE 的函数
isFirstInParagraph(spanList[0]);  //ie. the word "The"

和 FALSE 为

isFirstInParagraph(spanList[1]);  // ie. the word "dog."

在以下情况下,两个跨度都将返回 FALSE,因为这两个都不是段落中的第一件事。:

<p>The <span class="myClass">quick</span> brown fox jumps over the lazy <span class="myClass">dog.</span></p>

我很想附上一些半工作代码,但我所做的一切都没有接近。在我看来,解决这个问题的一种方法是找到 SPAN 相对于段落的范围偏移,并查看它是否为零。但是我花了几个小时阅读文档,但无法弄清楚。我不禁认为这是因为我对 javascript/html 中的一般概念和术语缺乏了解。

可能相关的事情:

  • 段落可能有也可能没有第一个单词。
  • 并非所有 myClass 跨度都必须在段落中,例如,它们可能在标题中。
  • myClass 跨度可以是斜体或粗体等。
  • 这需要是 javascript 而不是查询。
  • 它适用于原生 iOS 应用程序的 UIWebview 中。我会假设 Safari 兼容的东西会起作用。

提前致谢

【问题讨论】:

  • 获取所有跨度然后测试它们的位置是错误的方法。只需检查段落的第一个子元素是否是 span 元素,但请注意,如果 &lt;p&gt;&lt;span&gt; 标记之间存在不可见的空格,这可能会产生误导。
  • 感谢 Alnitak。无论如何,我必须遍历所有跨度,以获取有关它们的其他信息(我的问题中没有包含这些信息),所以我认为这可能是合适的地方。

标签: javascript html paragraph


【解决方案1】:

支持浏览器的函数,用于查找 所有 span 元素,它们是各自父元素的第一个子元素:

function allFirstChildSpans () {
    return document.querySelectorAll('span:first-child');
}

JS Fiddle demo.

一个测试给定 span 元素是否是其父元素的第一个子元素的函数:

function isFirstChild(elem) {
    return null === elem.previousSibling;
}

JS Fiddle demo.

假设您只想测试 span 是否是其父节点的第一个子节点,这实际上要简单得多:

JS Fiddle demo.

function isFirstChild(elem) {
    return elem.firstChild === elem;
}

JS Fiddle demo.

还有一个简单的原型扩展,用于将 isFirstChild() 方法添加到单个 HTMLElement 节点:

HTMLElement.prototype.isFirstChild = function () {
    return this.parentNode.firstChild === this;
};

JS Fiddle demo.

【讨论】:

  • 请注意,您没有使用allChildren 变量
  • @Gaby:谢谢,这是一个初步考虑的解决方案,因为使用更正的代码进行了编辑。
  • 谢谢,但不幸的是我认为我没有清楚地解释自己,我已经编辑了我的问题。如果跨度是段落中的第一个孩子,这似乎会返回,但如果它是最重要的,我希望它返回,包括任何文本。因此,例如,这里的两个 span 都应该返回 false:

    quick 棕色狐狸跳过了懒惰的 dog。

  • 出于兴趣,我不得不使用“不支持previousElementChild的浏览器”版本才能让它在我的iOS应用程序中运行。
  • @narco:在这种情况下,最后一个 code-sn-p 应该可以满足您的需要;虽然我有点惊讶你担心空白/空文本节点是previousSibling。
【解决方案2】:

像这样获取所有跨度的列表:

spanList = document.getElementsByTagName("span"); // all spans in document

那么函数应该是这样的:

function isFirstInParagraph(span)
    {
        var p = span.parentNode;

        if (p.nodeName === "P") // is span contained within 'p'
        {
            if (p.firstChild === span)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }

    }

【讨论】:

  • 我试过这个,但如果跨度是段落中多个跨度中的第一个,它似乎会返回。我想也许我不清楚我想要什么,所以我编辑了这个问题。只有当它是段落中的第一件事,而不仅仅是第一个跨度时,我才需要返回 true。无论如何,谢谢。
  • 你的意思是第一个标签或第一个文本。如果您有

    textdog 并要求该跨度,您会认为是假的吗?

  • 我编辑了我的答案。现在,如果您要求的 span 是段落中的第一个字符,它只会返回 true。
  • 您正在使用所有跨度,因此一个段落中可以有相同的 outerHTML 跨度。您的代码将在这段&lt;p&gt;&lt;span&gt;x&lt;/span&gt;somethings here&lt;span&gt;x&lt;/span&gt;&lt;/p&gt; 的两个范围内返回true。我更喜欢获取第一个子节点并比较对象。
  • 现在你错过了 if (p.innerHTML.indexOf(span.outerHTML) === 0) 部分
【解决方案3】:

如果你想在 span 之前忽略纯文本(不是标签)那么你可以使用

function isFirstInParagraph(span){
    var parent = span.parentNode;
    return parent.getElementsByTagName('*')[0] === span;
}

http://jsfiddle.net/gaby/gd2q9/的演示

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2018-10-20
    • 2018-05-06
    • 1970-01-01
    相关资源
    最近更新 更多