HTML自定义表单元素不发送提交事件

时间:2019-07-19 12:23:11

标签: javascript

创建了一个自HTMLFormElement派生的自定义HTML元素,并在构造函数中为“ submit”事件添加了侦听器。元素已正确注册,但从未调用提交处理程序...

class MyForm extends HTMLFormElement {
  constructor() {
    super();
    this.addEventListener('submit', this.mySubmit);
  }

  mySubmit() {
    console.log('mySubmit was called');
  }

  connectedCallback() {
    console.log('Custom form element added to page.');
  }
}

customElements.define('my-form', MyForm, {
  extends: 'form'
});
<!DOCTYPE html>
<html lang="de-DE">

<head>
  <title>My Form</title>
  <meta charset="utf-8">
  <!--<script src="myform.js" async="true"></script>-->
</head>

<body>
  <h1>My Form</h1>
  <my-form>
    <p><input type="input" value="Whoa!" /></p>
    <p><button type="submit">Submit</button></p>
  </my-form>
</body>

</html>

3 个答案:

答案 0 :(得分:3)

如自定义元素界面的文档中所述,您必须使用is=""属性将自定义元素功能“绑定”到HTML。

自定义元素之间似乎存在差异:

1)可以使用<my-form>样式编写使用自己的影子DOM(“独立元素”,“自治元素”)并因此被迫扩展HTMLElement(而不是HTMLFormElement)的元素。在HTML内。

2)对于不扩展HTMLElement而是尝试扩展其他内容的自定义元素,例如HTMLFormElement,似乎您需要使用<form is="your-defined-name"></form>,(“ “)

https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#Customized_built-in_elements

class MyForm extends HTMLFormElement {
  constructor() {
    super();
    this.addEventListener('submit', this.mySubmit);
  }

  mySubmit() {
    console.log('mySubmit was called');
  }

  connectedCallback() {
    console.log('Custom form element added to page.');
  }
}

customElements.define('my-form', MyForm, {
  extends: 'form'
});
<!DOCTYPE html>
<html lang="de-DE">

<head>
  <title>My Form</title>
  <meta charset="utf-8">
  <!--<script src="myform.js" async="true"></script>-->
</head>

<body>
  <h1>My Form</h1>
  <form is="my-form">
    <p><input type="input" value="Whoa!" /></p>
    <p><button type="submit">Submit</button></p>
  </form>
</body>

</html>

答案 1 :(得分:0)

通过添加自定义is=""事件来继承HTMLElement,可以在没有mySubmit的情况下进行操作,请考虑以下事项:

'use strict';
class MyForm extends HTMLElement {
  constructor() {
    super();
    this.addEventListener('mySubmit', this.mySubmit);
    debugger;
  }
  get action() {
    return this.getAttribute('action') || window.location.href;
  }
  mySubmit() {
    console.log('mySubmit was called');
    window.location = this.action;
  }

  connectedCallback() {
    console.log('Custom form element added to page.');
    this.querySelector('[type=mySubmit]').onclick = () => {
      this.dispatchEvent(new CustomEvent('mySubmit')); //,{type: 'submit'});
    }
  }
}

customElements.define('my-form', MyForm); //, {extends: 'form'});
<!DOCTYPE html>
<html lang="de-DE">

<head>
  <title>My Form</title>
  <meta charset="utf-8">
  <!--<script src="myform.js" async="true"></script>-->
</head>

<body>
  <h1>My Form</h1>
  <my-form action="https://www.google.com">
    <p><input type="input" value="Whoa!" /></p>
    <p><button type="mySubmit">Submit</button></p>
  </my-form>
  <hr>
  <h1>My Form 2</h1>
  <my-form>
    <p><input type="input" value="Whoa2!" /></p>
    <p><button type="mySubmit">Submit</button></p>
  </my-form>
</body>

</html>

答案 2 :(得分:0)

非常感谢您的帮助!仅缺少一小段代码即可实现它……元素中的'action =“#”'。最好的问候,奥利弗

现在,代码如下所示,并且可以按预期工作:

1 - load_proxy -> reads list of proxies from a file and puts them into an array
2 - load_accounts -> reads list of accounts from a file and puts them into an array
3 - init-> opens a browser , in a while loop fetching accounts and calling the next function  
4 - open_tab-> opens a tab in the browser and checks the account and calles the next function to log the result 

5 - wite_to_file-> writing the result into a text file 



const puppeteer = require('puppeteer');
const fs = require('fs');
const PROXYSTACK = [] ;
const PROXYDB = [] ;
const ACCOUNTSTACK = [] ;
const ACCOUNTDB = [] ;
var   inprogress = false ;



setInterval(()=>load_proxy() , 5000 );
setInterval(()=>load_accounts() , 5000 );
setInterval(function(){

    if( !inprogress)
    {
        init();
    }

} , 2000 );


function load_proxy(){

    var lines = fs.readFileSync('./proxy.txt', 'utf-8')
        .split('\n');

        for(var i = 0 ; i< lines.length ; i++ )
        {
            let line  = lines[i];
            if(line == '' || typeof line == 'undefined')
            {
                continue ;
            }

            line = line.replace('\r' , '');
            if(PROXYDB.includes(line))
                continue ;

            PROXYSTACK.push(line);
            PROXYDB.push(line);

        }

}
function load_accounts(){

    var lines = fs.readFileSync('./accounts.txt', 'utf-8')
        .split('\n');

        for(var i = 0 ; i< lines.length ; i++ )
        {
            let line  = lines[i];
            if(line == '' || typeof line == 'undefined')
            {
                continue ;
            }

            line = line.replace('\r' , '');
            if(ACCOUNTDB.includes(line))
                continue ;

            ACCOUNTDB.push(line);
            ACCOUNTSTACK.push(line);

        }

}



async function init(){

    inprogress = true ;

    if(PROXYSTACK.length <= 0 )
    {
        console.log('========================================= > OUT OF PROXY !!!!');
        inprogress = false ;
        return ;
    }

    if(ACCOUNTSTACK.length <= 0 )
    {
        console.log('========================================= > OUT OF ACCOUNT !!!!');
        inprogress = false ;
        return ;
    }

    var ipport =  PROXYSTACK.pop().replace('\r' , '');
    console.log(` ----> current ${ipport} `);

    var  browser = await puppeteer.launch({headless: true        ,  args: ['--proxy-server=' + ipport  , '--no-sandbox', '--disable-setuid-sandbox' , ]});
    browser._process.once('close', () => {
        console.log(' ------------------------  closed !');
        inprogress = false;
    });
    browser.on('disconnected', () => {
        console.log(' ------------------------  disconnecte !');
        inprogress = false;
    });

    var  mainpage = await browser.newPage();
    await mainpage.setViewport({width: 1200, height: 1000});

    while( inprogress )
    {
        var line_number = ACCOUNTSTACK.length ;
        if(line_number == 0 )
        {
            inprogress = false ;
            break ;
        }
        var account = ACCOUNTSTACK.pop();
        console.log(account);


        var check = await open_tab(account , line_number , mainpage);
        if(check === 'fatalerror')
        {
            console.log('========================================= >  FATAL ERROR CHANGING IP ');
            try {
                await browser.close();
            }
            catch (e) {

            }

            inprogress = false ;
        }


    }


}


async function open_tab(account  , line_num , mainpage ) {

    console.log(`  ---- > checking  ${account} `);
    let link = `https://example.com`;



    try {


        let user_password = account.split(':');


        if(!await mainpage.$('#username'))
        {
            console.log('...loading login page');
            await mainpage.goto(link , {timeout: 0});
            console.log('...done');

            if(await mainpage.$('.fatalerror'))
            {
                ACCOUNTSTACK.push(account);
                await mainpage.screenshot({path:  './fatalerror-a-'+line_num+'.jpg'  });
                return 'fatalerror';
            }

            console.log('...waitnign for login filds');

            await Promise.race([
                mainpage.waitForSelector('#username'),
                mainpage.waitForSelector('.fatalerror'),
            ]).catch(function (error) {
                throw new Error(error);
            });
            if(await mainpage.$('.fatalerror'))
            {
                ACCOUNTSTACK.push(account);
                await mainpage.screenshot({path:  './fatalerror-b-'+line_num+'.jpg'  });
                return 'fatalerror';
            }
            console.log('...done');



        }


        console.log('...typing user password');

        await mainpage.$eval('#username', (el ) => el.value = '' );
        await mainpage.$eval('#password', (el ) => el.value = '' );

        await mainpage.type('#username', user_password[0], {delay: 10})
        await mainpage.type('#password', user_password[1], {delay: 10})
        console.log('...done');

        console.log('...clicking login button');
        await mainpage.click('button.primary-button')

        await Promise.race([
            mainpage.waitForSelector('.theme-noticeerror-font'), // timeout
            mainpage.waitForSelector('.empty-inbox'), 
            mainpage.waitForSelector('.new-message'), 
            mainpage.waitForNavigation(),
        ]).catch(function (error) {
            throw new Error(error);
        });
        console.log('...done');

        if (await mainpage.$('.theme-noticeerror-font'))
        {
            console.log(account + '-- '+ line_num +' --> TIMEOUT')
            ACCOUNTSTACK.push(account);
            await mainpage.screenshot({path:  './timeout'+line_num+'.jpg'  });
            return 'fatalerror';

        }
        else if (await mainpage.$('.empty-inbox'))
        {
            console.log(account + '-- '+ line_num +' --> empty');
            wite_to_file('empty.txt' , account );

        }
        else if (await mainpage.$('.new-message'))
        {
            console.log(account + '-- '+ line_num +' --> new message')
            wite_to_file('newmsg.txt' , account );

        }



    }
    catch(e)
    {
        console.log(`--------ERRRO----${account}-${line_num}---------------------`);
        await mainpage.screenshot({path:  './images/error'+line_num+'.jpg'  });
        ACCOUNTSTACK.push(account);
        const html =  await mainpage.content();
        fs.writeFileSync('./images/error'+line_num+'.html', html);

    }
}


function wite_to_file( file , acc){

    fs.appendFile('./' + file ,   `${acc}\n` , function (err) {})

}