gpt4 book ai didi

javascript - JS>将HTML onclick事件绑定(bind)到自定义元素v1对象

转载 作者:行者123 更新时间:2023-11-29 15:19:35 26 4
gpt4 key购买 nike

TL; DR

如何将div元素的内联onclick-event的回调绑定(bind)到div所在的自定义元素?
我想使用onclick="foo('bar')"而不是onclick="this.foo('bar')"

长版:

自定义元素可单击的div 附加到DOM的步骤如下:

<my-element>
<!-- 1. works -->
<div onclick="this.foo('bar')">click me</div>

<!-- 2. not working -->
<div onclick="foo('bar')">click me</div>

<!-- edit: 3. playground (works) -->
<div onclick="me.foo('bar')">click me</div>
</my-element>

...现在我想将 foo() -function绑定(bind)到我的自定义元素( <my-element>)。

第一种解决方案:此处 onclickfoo()( this)上调用 this.foo() -function,其中 this稍后绑定(bind)到我的“自定义元素”(请参见以下代码)。

第二种解决方案:在这里我想省略 this.并将其再次绑定(bind)到我的自定义元素。但是:尽管绑定(bind)在上述解决方案(1.)中有效,但它并非没有前置的 this.-这是我的问题。

编辑的第三种解决方案:使用代理将函数调用从 me投影到 this自定义元素。它不能解决问题,但是至少我尝试过。

因此问题是:如何使解决方案2正常工作?

我的Custom Element v1类-包括我尝试过的一些代码:
class MyElement extends HTMLElement
{
constructor()
{
super()
}

connectedCallback()
{
var self = this

this.addEventListener('click', this.handleClick, true)

// Proxy for solution 3
window.me = new Proxy({},
{
get: function(target, prop)
{
return self[prop]
}
})
}

handleClick(ev)
{
console.log(ev.target.onclick)
// returns: ƒ onclick(event) { foo("bar") }
// > is typeof function

// provides the binding to "this" for solution 1
ev.target.onclick = ev.target.onclick.bind(this)

// call
ev.target.onclick()
// works on first solution
// throws error in 2nd solution: foo is not defined
}

foo(str)
{
console.log(str)
}
}

customElements.define('my-element, MyElement)

一些解释:
  • 使用addEventListener并将其第3个参数(useCapture)设置为true,我在执行之前捕获了事件。
  • 我能够将foo() -function登录到控制台。它封装在一个可调用的函数中,这似乎就是为什么我无法将上下文绑定(bind)到foo() -function本身的原因。
  • 通过ev.target.onclick()调用该函数会引发错误,因为在给定上下文(window)中不存在foo() -function。

  • 一些想法:
  • React 做类似的事情(我还没有使用React),但是我看不到如何转移他们的解决方案,因为他们最终以某种方式预处理了onclick事件(使用eval?)。这可能是其语法为onclick={foo}而不是onclick="foo()"的原因。我也不知道React是否可以传递参数。
    请参阅:https://facebook.github.io/react/docs/handling-events.html
  • 关于此,可能是一个问题,在我的解决方案中,foo()函数可能已经在窗口上下文中以某种方式被调用了,这意味着它的上下文已经设置并且不能再更改...?无论如何,尝试设置不带括号的onclick="foo"并在以后调用它也不起作用。

  • 很好地阅读以下主题:

    http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/

    因此,我根本不知道是否有解决方案。无论如何,欢迎提出想法或解释!

    编辑2:固定。

    当从元素类内部创建并附加元素时,它也起作用:
    var el = document.createElement('div')
    el.innerHTML = 'click me'
    el.onclick = () => {
    this.foo('bar')
    }
    this.appendChild(el)

    编辑3,4,5:
    进行了一些操作(请参阅解决方案3),并将Proxy对象分配给全局变量('me'),该变量将对 this Custom Element-kinda __noSuchMethod__的任何函数调用进行投影。因此...选择一个1或2个字符的变量可以通过不键入 this.而不是 me.vm.甚至 i.来节省键盘上的至少几个击键...到目前为止的最佳解决方案。伤心!
    不幸的是,解决方案3也不能用作所有元素的通用模式,因为它仅将上下文限制为一个(即最后连接的)自定义元素。

    编辑6-初步结论

    事实证明,似乎无法将html-inline onclick-event( onclick="foo('bar')")绑定(bind)到其中嵌入了clickable元素的Custom Element类。

    因此,最明显的方法是:

    A)使用this关键字(如 onclick="this.foo('bar')")并将其绑定(bind)到上述类。为什么 this.foo()是可绑定(bind)的,而没有 foo()this为什么不绑定(bind),目前尚不清楚。我想知道bc这两个函数并没有真正的区别-两者都已经绑定(bind): this.foo()绑定(bind)到了clickable元素, foo()绑定(bind)到了 window

    B)使用@Supersharp建议的eval,即,将事件侦听器添加到“自定义元素”,侦听点击,获取onclick属性的值作为字符串,并在其前添加“this”。字符串,并有效地做到这一点: eval("this." + "foo()")

    C)除了内联onclick之外,我倾向于使用事件委托(delegate)并使用声明性html属性来指示行为。为此,再次将click事件侦听器添加到Custom Element类:
    myElement.addEventListener('click', function(ev) {

    if (ev.target.dataset.action)
    {
    this[ev.target.dataset.action]()
    }

    }, false)

    您的clickable元素看起来像 <div data-action="next">Show more</div>

    最佳答案

    一种解决方案是在eval()的串联和"this."元素的onclick属性的内容上使用event.target

    不要忘记使用event.stopPropagation()停止调度事件。

    handleClick( ev )
    {
    eval( 'this.' + ev.target.getAttribute( 'onclick' ) )

    ev.stopPropagation()
    }

    如果您不想使用 eval(),则应该解析 ev.target.getAttribute( 'onclick' )的内容以提取函数名et参数,然后调用element方法(如果存在):
    if ( typeof this.name === 'function ) 
    this[name](arguments)

    更新

    我建议您将 id赋予自定义元素,然后调用id +方法:
    <my-element id="me">
    <div onclick="me.foo('bar')">click me</div>
    </my-element>

    这样,您无需重定向/捕获事件,并且 div可以位于元素中的任何位置。

    关于javascript - JS>将HTML onclick事件绑定(bind)到自定义元素v1对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45501054/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com