Javascript绑定函数未按预期传递参数
我希望有人能解释从事件侦听器向函数传递多个参数时的绑定行为。我找不到任何解释 我有一个执行JS函数onclick的按钮。 我试图在设置事件侦听器时将一些参数绑定到函数 无论何时执行函数,“CategoryId”都会正确通过,但“SubheadingText”会作为事件对象通过,就像“event”一样 这有什么原因吗?第二个事件对象来自哪里 下面是JS代码 小提琴可以在这里买到:Javascript绑定函数未按预期传递参数,javascript,Javascript,我希望有人能解释从事件侦听器向函数传递多个参数时的绑定行为。我找不到任何解释 我有一个执行JS函数onclick的按钮。 我试图在设置事件侦听器时将一些参数绑定到函数 无论何时执行函数,“CategoryId”都会正确通过,但“SubheadingText”会作为事件对象通过,就像“event”一样 这有什么原因吗?第二个事件对象来自哪里 下面是JS代码 小提琴可以在这里买到: 开始放置参数,从第二个参数开始: faqCategoryButtons.addEventListener('click
开始放置参数,从第二个参数开始:
faqCategoryButtons.addEventListener('click', categoryNavigation.bind(null, categoryId, subheadingText, event));
始终将上下文(此
)作为第一个参数接收,因此在您的情况下,其他参数将被抵消:
faqCategoryButtons.addEventListener('click',
categoryNavigation.bind(
null, /* <- context */
categoryId,
subheadingText,
event
)
);
faqCategoryButtons.addEventListener('click',
分类导航(
null,/*第一个参数始终将是您尝试绑定“”对象的函数,是分配给函数所具有的参数的以下值。如果您选中,单击按钮后,您将获得以下值:
this: "mycatid",
categoryId: "my cat text"
subheadingText: Event
event: MouseEvent
因此,为了使代码按预期工作:
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
faqCategoryButtons.addEventListener('click', categoryNavigation.bind(null, categoryId, subheadingText, event));
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}
在本例中,我添加了一个额外的“null”使其工作,因为我知道您没有使用“this”,但是,您可以添加任何值,它将成为函数的“this”
编辑:回复评论的问题
看起来即使当我
按此顺序将参数绑定到函数
categoryNavigation.bind(null,categoryId,subheadingText,event)但是
当我定义函数时,参数的顺序应该是这样的
类别导航(类别ID,副标题文本,上下文,事件){}
当
函数被调用了吗
正如我在回答中提到的,绑定时的第一个参数是“this”,我称之为上下文,这是函数所做的真正的“重排”。除此之外,参数的顺序是相同的。然而,需要考虑的是,“bind”返回的函数已经包含了这些参数“绑定”到旧函数,应该再次调用它
在您的案例中,您绑定了null、categoryId、subheadingText、event。但是在显示的代码中,只定义了categoryId和subheadingText,而event没有定义。这意味着您绑定在那里的事件从技术上讲应该是“未定义的”——但可能是代码此时的随机事件值点-。另一方面,单击确实会将其自身的“事件”值作为参数返回,因此最终,在代码中会有一个单击事件,它将调用一个事先绑定的函数“null,cathegoryId,subheadingText,”,当事件发生时,会调用该事件并将单击的事件放置在那里(但没有空间放置该事件,因为所有参数都已定义)
换句话说,您的代码(在此绑定修复之后)
相当于:
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
function categoryNavigationBinded(eventForTheclick){
const categoryNavigationThis = cagegoryNavigation.bind(null); // in the fixed code, categoryNavigation has its "this = null"
categoryNavigationThis(categoryId, subheadingText, event) // note that event is not defined, and for what I know is "undefined"
}
faqCategoryButtons.addEventListener('click', categoryNavigationBinded);
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}
对于代码,我假设您希望执行以下操作:
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
function categoryNavigationBinded(eventForTheclick){
const categoryNavigationThis = cagegoryNavigation.bind(null); // in the fixed code, categoryNavigation has its "this = null"
categoryNavigationThis(categoryId, subheadingText, eventForTheclick) // here I am placing the click's event into the 3rd categoryNavigation parameter
}
faqCategoryButtons.addEventListener('click', categoryNavigationBinded);
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}
这将是“扩展”版本,因此我可以解释将发生什么,而使用绑定的“短版本”与您在代码中使用的方式相同:
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
faqCategoryButtons.addEventListener('click', categoryNavigation.bind(null, categoryId, subheadingText)); // the last parameter, "event", will be the parameter the click will place its own event
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}
TLDR:除了第一个“this”之外,参数在绑定中不会真正重新组织,但是在代码中,您在真正拥有真正的事件值之前定义了“event”参数,因此它“丢失”(并在单击时作为“第五个”参数发送)试试这不是一个解决问题的描述。出了什么问题,您做了什么来解决它?感谢您的详细回答。看起来,即使我将参数绑定到函数,它也需要按以下顺序进行categoryNavigation.bind(null,categoryId,subheadingText,event)但是当我定义函数时,参数的顺序必须是categoryNavigation(categoryId,subheadingText,context,event){}调用函数时,参数是否会被重新排列?抱歉,这里的解释有点长,我无法向您展示示例,因此我将编辑我的回答,以尝试正确解决您的问题
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
function categoryNavigationBinded(eventForTheclick){
const categoryNavigationThis = cagegoryNavigation.bind(null); // in the fixed code, categoryNavigation has its "this = null"
categoryNavigationThis(categoryId, subheadingText, eventForTheclick) // here I am placing the click's event into the 3rd categoryNavigation parameter
}
faqCategoryButtons.addEventListener('click', categoryNavigationBinded);
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}
var faqCategoryButtons = document.getElementsByClassName('button-faq-cat')[0];
var categoryId = 'mycatid';
var subheadingText = 'my cat text';
faqCategoryButtons.addEventListener('click', categoryNavigation.bind(null, categoryId, subheadingText)); // the last parameter, "event", will be the parameter the click will place its own event
function categoryNavigation(categoryId, subheadingText, event){
if (event && event.preventDefault) {
event.preventDefault();
} else if (event) {
event.returnValue = false;
}
}