简体   繁体   English

如何将元素传递给javascript函数并访问第一个子元素

[英]How to pass element to javascript function and access the first child

I am creating check-boxes in my ASP.NET code behind a file in C#. 我在我的ASP.NET代码中创建了一个C#文件后面的复选框。 I am adding an attribute value before adding the control to the page, therefore ASP is adding the attribute to the span surrounding the check-box and the label for the text. 我在将控件添加到页面之前添加了一个属性值,因此ASP将该属性添加到复选框周围的范围和文本的标签。 It looks like this: 它看起来像这样:

<span data-bind="visible: showCheckBox(this)">
   <input id="" type="checkbox" name="ctl00$MainContent$SecondaryForm$ctl00" value="1">    
   <label for="">Outside Source</label>
</span>

I have a function called showCheckBox() written in Knockout.js. 我有一个名为showCheckBox()的函数,用Knockout.js编写。 It determines if the target checkbox should be displayed, based on the value of the selected item in the drop down list immediately preceding it. 它根据紧接在其前面的下拉列表中所选项的值来确定是否应显示目标复选框。 For example, if the value of the selected item in the drop down list is 1, then the target checkbox with a corresponding value of 1 would be visible. 例如,如果下拉列表中所选项的值为1,则可以看到对应值为1的目标复选框。 That function looks like this: 该函数如下所示:

function showCheckBox(span) {
   var value = span.firstChild.value;
   return value == reason();  
}

reason() is the view model variable that holds the value of the selected drop down list item. reason()是视图模型变量,它保存所选下拉列表项的值。 No matter what I do, I cannot get the value of the check-box to be sent correctly. 无论我做什么,我都无法正确发送复选框的值。 It is always undefined. 它总是未定义的。

The first child in this HTML is actually a textNode , which firstChild will return if that is what is found. 此HTML中的第一个子textNode实际上是一个textNode ,如果找到的话, firstChild将返回该textNode These are the actual characters it is returning: "↵ " (A return and a space). 这些是它返回的实际字符: "↵ " (返回和空格)。

You can use the firstElementChild property instead: 您可以使用firstElementChild属性:

function showCheckBox(span) {
    var value = span.firstElementChild.value;
    return value == reason();  
}

Also, don't forget to check the support tables for firstElementChild . 另外,不要忘记检查firstElementChild的支持表。

After thinking about it for a while also, a coworked suggested this solution. 在考虑了一段时间之后,一个同事提出了这个解决方案。

Instead of assigning the value of the check box as the ID that corresponds to the drop down list view model variable, he suggested I assign it in the data-bind attribute instead. 他没有将复选框的值指定为与下拉列表视图模型变量对应的ID,而是建议我在data-bind属性中指定它。 In my C# code behind file, that looks like this 在我的C#代码隐藏文件中,看起来像这样

cb.Attributes.Add("data-bind", String.Format("visible: showCheckBox({0})", reasonDetails[i].ReasonForSendingNoticeID.ToString()));

Which looks like this when displayed in HTML 在HTML中显示时看起来像这样

<span data-bind="visible: showCheckBox(1)" style="display: none;">
<input id="" type="checkbox" 
name="ctl00$MainContent$SecondaryForm$ctl00" value="Outside Source">
<label for="" style="display: inline;">Outside Source</label>
</span>

Then I changed the function as follows 然后我改变了如下功能

function showCheckBox(id) {
    return id == reason();
}

Doing it like so allowed us to directly pass the value into the function without having to pass the element or its child. 这样做允许我们直接将值传递给函数,而不必传递元素或其子元素。

Thank you for the help and suggestions. 感谢您的帮助和建议。

The problem is hidden, and it's because you're for a large part not using KnockoutJS at all. 问题是隐藏的,这是因为你很大程度上没有使用KnockoutJS You should check the docs for the KnockoutJS checked binding . 您应该检查KnockoutJS checked绑定的文档。

There should very likely be no reason to check the DOM inside view models, not even those handling visibility . 很可能没有理由在视图模型中检查DOM,甚至没有理由查看那些处理可见性的DOM Instead, use the view model . 而是使用视图模型 You haven't quite posted a complete minimal repro, but here's what it should more or less look like: 你还没有发布一个完整的最小repro,但这里应该或多或少看起来像:

 function ViewModel() { var self = this; self.reasons = [{id: 1, txt: "Main reason"}, {id: 2, txt: "Other reason"}]; self.reason = ko.observable(self.reasons[0]); self.showCheckBox = ko.computed(function() { return self.reason().id === 1; }); self.hasOutsideSource = ko.observable(false); }; ko.applyBindings(new ViewModel()); 
 pre { font-family: consolas; background: smoke; border: 1px solid #ddd; padding: 5px; margin: 5px; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <select data-bind="options: reasons, value: reason, optionsText: 'txt'"></select> <span data-bind="visible: showCheckBox"> <label> <input data-bind="checked: hasOutsideSource" type="checkbox" name="ctl00$MainContent$SecondaryForm$ctl00" value="1"> Outside Source </label> </span> <hr> This would be sent to your server / debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre> 

If you can't take the above approach, I strongly recommend considering skipping the use of KnockoutJS, because it'll probably cause you more trouble than it'll help you if you do to much DOM manipulation on your own. 如果你不能采取上述方法,我强烈建议考虑跳过使用KnockoutJS,因为它可能会给你带来更多的麻烦,如果你自己做了很多DOM操作,它会帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM