【问题标题】:Select the element right before the script tag选择脚本标签之前的元素
【发布时间】:2020-05-18 14:10:22
【问题描述】:

如何在不编辑 DOM 的情况下选择下面代码中的第一个 input(如果需要,使用 jQuery)?

<input type="text"/> <!-- The element I want to select -->
<script>
    // Select the input above
</script>
<input type="text"/>

请注意,在此代码示例前后有未知数量的输入和脚本标签,因此$("input:eq(1)") 之类的解决方案将不起作用。

棘手的部分是选择位于执行当前 JavaScript 的 script 标记之前的 input

无需问我为什么我也想这样做,这纯粹是为了美观,如果可能的话,我想这样做而不必在我的输入中添加随机 id。

编辑
这就是大多数答案不起作用的原因:http://jsfiddle.net/2WqfP/

【问题讨论】:

    标签: javascript jquery jquery-selectors


    【解决方案1】:

    脚本总是在加载时运行,因此运行的&lt;script&gt; 标记将始终是页面上的最后一个。使用纯 JS 可以这样得到:

    var scripts = document.getElementsByTagName('script'),
        currentScript = scripts[scripts.length - 1];
    

    编辑:我之前弄错了。要获取此时的输入,您需要获取前面的兄弟,因此您将使用previousSibling。另外,请参阅下面关于文本节点和潜在解决方案的系统评论。

    var scripts = document.getElementsByTagName('script'),
        currentScript = scripts[scripts.length - 1],
        input = currentScript.previousSibling;
    

    你也可以使用 jQuery:

    var currentScript = $('script').last();
    

    一旦你有了脚本,你就可以很容易地得到前面的输入:

    var input = $('script').last().prev();
    

    【讨论】:

    • 它们确实在加载时运行,但是当它们被附加到 DOM 的开头时(例如在以这种方式工作的灯箱中),我们不能确定正在执行的一个是 DOM 中的最后一个。
    • @user1728278:附加脚本与问题中的情况截然不同。但如果它被附加,那么执行附加的代码必须已经知道input 的位置(因为script 是相对于input 放置的),因此能够选择它。
    • @thesystem 我想我忘记了重要的一点,但我希望 前后有未知数量的输入和脚本标签位可以弥补这一点。关于您现在的提议,在打印上述灯箱时,inputscript 标记都是由 PHP 生成的。因此,您的解决方案不适用于此处:-/
    • 如果是 PHP 打印的,那是服务器端的。从客户端/JS 的角度来看,它就像是纯 HTML 一样。这应该仍然有效;你试过了吗?
    • @@newtron: .previousSibling 因文本节点而无法工作。你可以使用.previousElementSibling,但你会失去一些浏览器支持。 @user1728278:如果两者都是由 PHP 生成并动态加载,则需要不同的方法。如果你说你想要一段代码可以解决你的问题的任何可能的变化,那么你不太可能找到一个。您需要针对手头的问题编写代码。该问题的变化通常需要解决方案的变化。
    【解决方案2】:

    这是jsfiddle showing my solution

    $("input:last").val("test");
    

    这是因为当到达脚本时,紧接在其前面的输入是要创建的最后一个输入 - 以下&lt;input&gt; 尚未添加到 DOM。如果您在页面加载后运行代码(即在 onload 偶数处理程序中),这将不起作用。

    值得注意的是,我个人更喜欢 id,这样您就不必依赖内联 JavaScript(这通常是个坏主意)。

    【讨论】:

    • 它在大多数情况下都可以工作,但不幸的是,代码 sn-p 有时会加载到灯箱中,该灯箱会插入到 DOM 的开头。不过谢谢!
    • 关于你的最后一句话,我个人会避免使用 id 和内联 JavaScript,但你知道练习、遗留代码和一切......
    • @user1728278,如果您必须在页面加载后执行此操作,那么我认为任何解决方案都必须包含 id(或一些更人为的标记形式,您可以将其放入旧代码中)。
    【解决方案3】:

    内联脚本总是在解析时运行,而

    <input type="text"/> <!-- The element I want to select -->
    <script>
        var inputs = document.querySelectorAll('input');
        var above_input = inputs[inputs.length - 1];
    </script>
    <input type="text"/>
    

    【讨论】:

      【解决方案4】:

      试试这个:

      $("script").prev("input");
      

      【讨论】:

        【解决方案5】:

        你尝试过这样的事情吗?

        var input = $('script').prev();
        

        http://api.jquery.com/prev/

        【讨论】:

          【解决方案6】:

          原生 DOM 解决方案:

          var all = document.getElementsByTagName("*");
          var input = all[all.length - 2];
          

          script 将是页面运行时的最后一个元素,因此input 将是倒数第二个。

          【讨论】:

            最近更新 更多