【问题标题】:Elements inside custom HTML tag aren't initialised in constructor自定义 HTML 标记内的元素未在构造函数中初始化
【发布时间】:2018-04-25 04:12:45
【问题描述】:

我需要访问我创建的自定义标签<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 文件中,(仅适用于谷歌浏览器)

<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 中的类生命周期有关。但是找不到合适的功能

【问题讨论】:

  • 看起来像是this混淆的典型案例。将function(evt) 替换为evt =&gt; 的箭头语法,以保持this 相同。或者,将.bind(this) 应用于该回调函数(在其右大括号之后)。
  • 如果第一个问题解决了,可能是另一个问题。但主要问题是在未定义的对象上调用了“addEventListener”。 (对象formTag尚未识别)

标签: javascript html javascript-1.7


【解决方案1】:

三个问题及解决方案:

  • this.formTag 未定义,因为自定义标签的实例是在加载文档之前创建的,因此 this.getElementsByTagName("form")[0] 未定义。
    解决方案: 放置@987654323 @ 在ready 回调函数中。

  • $('#myform').submit() 将在不触发 submit 事件的情况下提交表单。
    解决方案: 在您的 HTML 中包含一个不可见的提交按钮,并触发点击它而不是调用submit 方法。

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

    JS:

    $('#submitButton').click();
    
  • addEventListener 回调中this 不是指您的自定义对象,而是指您调用addEventListener 的元素。
    解决方案:替换@987654333 @@this.submit()

【讨论】:

  • 我执行了它,它按照你建议的方式工作。关于 this,在 addEventListener 回调中,我认为是我需要删除 formTag 的地方,因为其中的 this 指的是表单对象,而this 外部指的是自定义对象。我也很喜欢隐藏按钮的技巧;这让我感到很傻,我以前从未想过!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 2014-05-19
  • 1970-01-01
相关资源
最近更新 更多