Javascript绑定函数未按预期传递参数

Javascript绑定函数未按预期传递参数,javascript,Javascript,我希望有人能解释从事件侦听器向函数传递多个参数时的绑定行为。我找不到任何解释 我有一个执行JS函数onclick的按钮。 我试图在设置事件侦听器时将一些参数绑定到函数 无论何时执行函数,“CategoryId”都会正确通过,但“SubheadingText”会作为事件对象通过,就像“event”一样 这有什么原因吗?第二个事件对象来自哪里 下面是JS代码 小提琴可以在这里买到: 开始放置参数,从第二个参数开始: faqCategoryButtons.addEventListener('click

我希望有人能解释从事件侦听器向函数传递多个参数时的绑定行为。我找不到任何解释

我有一个执行JS函数onclick的按钮。 我试图在设置事件侦听器时将一些参数绑定到函数

无论何时执行函数,“CategoryId”都会正确通过,但“SubheadingText”会作为事件对象通过,就像“event”一样

这有什么原因吗?第二个事件对象来自哪里

下面是JS代码

小提琴可以在这里买到:


开始放置参数,从第二个参数开始:

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;
  }
}