GetElementById элемента управления ASP.NET продолжает возвращать «ноль» - PullRequest
2 голосов
/ 22 июля 2011

Я отчаянно потратил больше часа, пытаясь решить эту проблему.Я пытаюсь получить доступ к узлу в DOM, который создан из элемента управления ASP.NET.Я использую точно такой же идентификатор, и я вижу, что они совпадают при просмотре исходного кода HTML после отображения страницы.Вот мой код [ИЗМЕНЕНО в соответствии с предложениями, но все еще не работающий]:

Заголовок ASP.NET

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    <script type="text/javascript">
    $(document).ready(
        var el = document.getElementById('<%= txtBox.ClientID %>');
        el.onchange = alert('test!!');
    )
    </script>
</asp:Content>

Тело ASP.NET

<asp:TextBox ID="txtBox" runat="server"></asp:TextBox>

Результирующий Javascript &HTML сверху

<script type="text/javascript">
$(document).ready(
    var el = document.getElementById('MainContent_txtBox');
    el.onchange = alert('test!!');
)
</script>
...
<textarea name="ctl00$MainContent$txtBox" id="MainContent_txtBox"></textarea>

Я могу только предположить, что скрипт загружается до того, как идентификатор элемента управления был разрешен, но когда я смотрю на временную шкалу с помощью функции «Проверка элемента» в Chrome, оказывается, что это недело.Когда я создал обычный текстовый блок для тестирования и реализации идентичного кода (конечно, с другим идентификатором), всплывающее окно срабатывает.

Что, черт возьми, мне здесь не хватает?Это сводит меня с ума>. <</p>

EDIT : странный код, который работает, но только при начальной загрузке страницы;стрельба по нагрузке, а не по обмену.Даже jQuery говорит, что .ready, по-видимому, не работает должным образом.Тьфу !!

$(document).ready(function() {
    document.getElementById('<%= txtBox.ClientID %>').onchange = alert('WORKING!');
})

Ответы [ 3 ]

5 голосов
/ 22 июля 2011

Предполагая, что отображаемая разметка отображается в таком порядке, проблема в том, что элемент еще не существует в то время, когда ваш JavaScript пытается его найти.

Либо переместите этот JS ниже элемента (предпочтительно прямо в конце тела), либо оберните его в что-то вроде обработчика событий готовности документа jQuery .

Обновление:

В ответ на ваши правки вы почти готовы, но (как уже упоминали другие) вам нужно назначить функцию событию onchange, а не результат возврата alert(). Примерно так:

$(document).ready(function() {
  // Might as well use jQuery to attach the event since you're already using
  //  it for the document ready event.
  $('#<%= txtBox.ClientID %>').change(function() {
    alert('Working!');
  });
});

Написав onchange = alert('Working');, вы просили JavaScript назначить результат метода alert() свойству onchange. Вот почему он выполнял его сразу при загрузке страницы, но никогда в действительности не отвечал на событие onchange (потому что вы не назначили эту функцию для запуска onchange).

2 голосов
/ 22 июля 2011

забрать JQuery.

Тогда вы можете

$(function()
{
    var el = document.getElementById('<%= txtBox.ClientID %>');
    el.onclick() { alert('test!!'); }
});
1 голос
/ 22 июля 2011

В других ответах указана ошибка (при попытке доступа к узлам DOM до того, как они появятся в документе), я просто укажу на альтернативные решения.

Простой метод

Добавьте элемент script в HTML ниже закрывающего тега элемента, к которому вы хотите получить доступ. В самой простой форме поместите его непосредственно перед закрывающим тегом body. Эта стратегия также может ускорить отображение страницы, поскольку браузер не приостанавливает загрузку HTML для скрипта. Общее время загрузки такое же, однако скрипты все равно должны быть загружены как исполняемые, просто этот порядок делает кажущимся более мягким для пользователя.

Используйте window.onload или

Этот метод поддерживается каждым браузером, но он запускается после загрузки всего контента, поэтому страница может казаться неактивной в течение короткого времени (или, возможно, долгого времени, если загрузка прекращается). Хотя это очень надежно.

Использовать функцию готовности DOM

Другие предложили jQuery, но вам может не потребоваться 4000 строк и 90 КБ кода только для функции, готовой к DOM. jQuery довольно запутанный, поэтому его трудно удалить из библиотеки. MyLibrary Дэвида Марка, однако, очень модульный и довольно легко извлекает только те биты, которые вы хотите. Качество кода также превосходно, по крайней мере, равноценно любой другой библиотеке.

Вот пример функции готовности DOM, извлеченной из MyLibrary:

var API = API || {};

(function(global) {

  var doc = (typeof global.document == 'object')? global.document : null;

  var attachDocumentReadyListener, bReady, documentReady,
      documentReadyListener, readyListeners = [];
  var canAddDocumentReadyListener, canAddWindowLoadListener,
      canAttachWindowLoadListener;

  if (doc) {
    canAddDocumentReadyListener = !!doc.addEventListener;
    canAddWindowLoadListener    = !!global.addEventListener;
    canAttachWindowLoadListener = !!global.attachEvent;

      bReady = false;
      documentReady = function() { return bReady; };
      documentReadyListener = function(e) {
        if (!bReady) {
          bReady = true;
          var i = readyListeners.length;
          var m = i - 1;
          // NOTE: e may be undefined (not always called by event handler)
          while (i--) { readyListeners[m - i](e); }
        }
      };

      attachDocumentReadyListener = function(fn, docNode) {
        docNode = docNode || global.document;
        if (docNode == global.document) {
          if (!readyListeners.length) {
            if (canAddDocumentReadyListener) {
              docNode.addEventListener('DOMContentLoaded',
                                        documentReadyListener, false);
            }
            if (canAddWindowLoadListener) {
              global.addEventListener('load', documentReadyListener, false);
            }
            else if (canAttachWindowLoadListener) {
              global.attachEvent('onload', documentReadyListener);
            } else {
              var oldOnLoad = global.onload;              
              global.onload = function(e) { 
                  if (oldOnLoad) { 
                    oldOnLoad(e); 
                  }
                  documentReadyListener();
              };
            }
          }
          readyListeners[readyListeners.length] = fn;
          return true;
        }
        // NOTE: no special handling for other documents
        // It might be useful to add additional queues for frames/objects
        else {
          if (canAddDocumentReadyListener) {
            docNode.addEventListener('DOMContentLoaded', fn, false);
            return true;
          }
          return false;
        }
      };

      API.documentReady = documentReady;
      API.documentReadyListener = documentReadyListener;
      API.attachDocumentReadyListener = attachDocumentReadyListener;

  }
}(this));

Использование в вашем случае:

function someFn() {
  var el = document.getElementById('MainContent_txtBox');
  el.onclick = function() { alert('test!!');
}

API.attachDocumentReadyListener(someFn);

или может быть предоставлена ​​анонимная функция:

API.attachDocumentReadyListener(function(){
  var el = document.getElementById('MainContent_txtBox');
  el.onclick = function() { alert('test!!');
};

Очень простые функции, готовые к DOM, могут быть выполнены в 10 строках кода, если вы просто хотите одну для конкретного случая, но, конечно, они менее надежны и не так многоразовы.

...