Элементы внутри пользовательского тега HTML не инициализируются в конструкторе

Мне нужно получить доступ к элементам внутри созданного мной тега <multi-nav>, Проблема в том, что конструктор не вызывается после инициализации этих элементов (что ожидается). В этом примере я не могу получить доступ к тегу формы, отображаемому в объекте formTag,

MultiNav.js

class MultiNav extends HTMLElement { 
    get formTag() { 
        return this.getElementsByTagName("form")[0];
    }

    get selectTag() {
        return this.formTag.getElementsByTagName("select")[0];
    }

    constructor () {
        super();
        this.formTag.addEventListener('submit', function(evt) {
            evt.preventDefault(); // to avoid error, by stopping form from submitting
            console.log("submitting ...");  // doesn’t log because formTag isn’t retrieved
             this.formTag.submit();
        }); 
    }
}


window.customElements.define('multi-nav', MultiNav);

Проблема в том что ошибка выдается после звонка addEventListenerБраузер говорит: Uncaught TypeError: Cannot read property 'addEventListener' of undefined

Пока в HTML-файле (работает только на Google Chrome)

<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'>
</script>

<script type="text/javascript">
$(document).ready(function() { 
 $('input[name=toggle]').change(function(){
    $('#myform').submit();
});
});
</script>

<script language="javascript1.7" src="/js/MultiNav.js">

</script>
<multi-nav>
<form id='myform' action="/action_page.php" method="POST"> 
    <div>
        <label><input type="radio" name="toggle" value="20"><span>$20</span></label>
        <label><input type="radio" name="toggle" value="50"><span>$50</span></label>
        <label><input type="radio" name="toggle" value="100"><span>$100</span></label>
        <label><input type="radio" name="toggle" value="500"><span>$500</span></label>
        <label><input type="radio" name="toggle" value="1000"><span>$1000</span></label>
    </div>
    <select name="stuff" form="myform" title="category" onchange="this.form.submit()">
        <option value="category"><button selected disabled>Category<button></option>
        <option value="home"><button>Home<button></option>
        <option value="electronics"><button>Electronics<button></option>
        <option value="cars"><button>Cars<button></option>
    </select>
</form>
</multi-nav>

Это должно быть как-то связано с жизненным циклом класса в JavaScript. Но я не мог найти подходящую функцию

1 ответ

Решение

Три проблемы и решения:

  • this.formTag не определяется, потому что экземпляр пользовательского тега создается до загрузки документа, и поэтому this.getElementsByTagName("form")[0] не определено
    Решение: место window.customElements.define('multi-nav', MultiNav); в пределах ready функция обратного вызова.

  • $('#myform').submit() отправит форму без submit событие срабатывает.
    Решение: включите в HTML-код невидимую кнопку отправки и нажмите ее вместо вызова submit метод.

    <input type="submit" id="submitButton" style="display:none">
    

    JS:

    $('#submitButton').click();
    
  • В пределах addEventListener Перезвоните this относится не к вашему пользовательскому объекту, а к элементу, к которому вы обращаетесь addEventListener,
    Решение: заменить this.formTag.submit(); от this.submit(),

Другие вопросы по тегам