当其他所有工作时,JavaScript无法通过页面上的ID找到一个特定元素

时间:2015-11-28 14:22:24

标签: javascript jquery html ruby-on-rails

我有一个奇怪的问题,使用JavaScript按ID查找元素。没有函数会对它运行,因为选择是未定义的。它与同一页面上的许多定义相同。此ID只有一个元素。而且,当我为周围的段落分配ID时,它的工作正常。所以,问题被绕过了。但是,我对这个问题非常好奇。我正在展示相关的项目。

此JavaScript是Rails应用程序的一部分,因此它使用application.js作为外部文件包含在内。它是一个包含许多功能的大文件,它们都可以工作,除非引用这个ID。而且,正如我所说,我在这个页面上以同样的方式选择了许多其他ID,没有任何问题。

我使用RubyMine并在整个应用程序中搜索与此问题相关的冲突和拼写错误。没有冲突,并且找到了对item_message的每个预期引用。 item_message包含在partial中,以及JavaScript轻松找到的其他引用。我在搜索之前搜索了语法错误,但没有找到。我重新排序页面和JavaScript中的项目无济于事。我根本不知道为什么这不起作用。

当我尝试使用class optional隐藏元素时,这很有效。但是,它还隐藏了其他不应隐藏的项目。

它的工作原理如下:

HTML:

  <p id="item_message_p">
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>

JavaScript的:

var item_message_p = $('#item_message_p');
select_item_spot_id.change(function () {
    var spot = $(this).val();
    if (spot != "") {
      $.getJSON('/spots', {spot: $(this).val()}, function (data) {
        if (data.name.toLowerCase() === 'sold') {
            item_message_p.hide();
        } else {
            item_message_p.show();
        }
      })
    }
});

它不会像这样工作,因为var item_message是未定义的:

HTML:

  <p>
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message"></p>

JavaScript的:

var item_message = $('#item_message');
select_item_spot_id.change(function () {
    var spot = $(this).val();
    if (spot != "") {
      $.getJSON('/spots', {spot: $(this).val()}, function (data) {
        if (data.name.toLowerCase() === 'sold') {
            item_message.hide();
        } else {
            item_message.show();
        }
      })
    }
});

3 个答案:

答案 0 :(得分:1)

根据Andy的建议,我最终检查生成的页面,发现另一个元素生成了相同的ID。这解释了这个问题。感谢所有帮助过的人。

答案 1 :(得分:0)

确保在查找元素之前加载页面。所以将代码包装在$(function () {...});中,如下所示:

$(function () {
    var item_message = $('#item_message');
    select_item_spot_id.change(function () {
        var spot = $(this).val();
        if (spot != "") {
          $.getJSON('/spots', {spot: $(this).val()}, function (data) {
            if (data.name.toLowerCase() === 'sold') {
                item_message.hide();
            } else {
                item_message.show();
            }
          })
        }
    });
});

这将使您的代码在dom准备好后执行。

此外,最好明确关闭input代码:

<input ..... />

注意斜杠。这种缺席也可能解释了这个问题,包括你在隐藏元素时注意到的破坏效应。

答案 2 :(得分:0)

您正在尝试访问select_item_spot_id.change(),但未定义select_item_spot_id。您定义了item_messageitem_message_p。您可能希望在onDOMReady事件侦听器中执行此操作,如@trincot所示。这个示例代码适用于我:

$(function () {
   var item_message = $('#item_message');
   var select_item_spot_id = $('#select_item_spot_id');
   select_item_spot_id.change(function () {
      var spot = $(this).val();
      // DEBUG
      if(item_message.length > 0)
         alert('works!');
      // END DEBUG
      if (spot != "") {
         $.getJSON('/spots', {spot: $(this).val()}, function (data) {
            if (data.name.toLowerCase() === 'sold') {
               item_message.hide();
            } else {
               item_message.show();
            }
         });
      }
   });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
  <select id="select_item_spot_id" name="select_item_spot_id">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
  </select>
  <input class="string optional form-control" placeholder="Message? (optional)" type="text" name="item[message]" id="item_message">
</p>