简体   繁体   English

有人可以解释此JavaScript的工作方式吗?

[英]Can someone explain how this JavaScript is working?

So I've managed to put together some JavaScript (with some help from others) which is basically a form that allows you to change the quantity of an item and add its value to the total if its checkbox is ticked (total displays in text field at bottom). 因此,我设法整理了一些JavaScript(在其他人的帮助下),这基本上是一种形式,允许您更改项目的数量并将其值添加到总计(如果选中了复选框)(文本字段中的总计显示)在底部)。

I understand some of it, its just the more complex parts of it that are confusing me (such as the logic). 我了解其中的一些,只是其中更复杂的部分使我感到困惑(例如逻辑)。 Could somebody talk me through or perhaps comment the main parts of my code so it can help me in understanding how the code is working. 有人可以说说我的意思,也可以评论我的代码的主要部分,以便它可以帮助我理解代码的工作方式。

<script type="text/javascript">
    function bump( which, bywhat ) {
        var form = document.items;
        var qty = form["qty" + which];

        qty.value = Number(qty.value) + bywhat;
        TotalCheckedValues( ); // in case user bumped an already checked line
    }

    function TotalCheckedValues( ) {
        var form = document.items;
        var total = 0;

        for ( var n = 1; n <= 4; ++n )
        {
            if ( form["cb"+n].checked ) // if the checkbox of the item is ticked
            {
                total += form["cb"+n].value * form["qty"+n].value; //
            }
        }

        form.Total.value = total.toFixed(2);
    }

    function validate(evt) {
        var theEvent = evt || window.event;
        var key = theEvent.keyCode || theEvent.which;
        var regex = /[0-9]|\./;

        key = String.fromCharCode( key );

        if(!regex.test(key)) {
            theEvent.returnValue = false;
            if (theEvent.preventDefault) {
                theEvent.preventDefault();
            }
        }
    }
</script>

</head>

<body>

<form name="items">

Item <input type="text" onkeypress='validate(event)'name="qty1" value="0"/>
<input type="button" onclick="bump(1,1)" value="+"/>
<input type="button" onclick="bump(1,-1)" value="-"/>
<input type="checkbox" name="cb1" value="20.00" 
onClick="TotalCheckedValues()"   />Service 1 (£20.00) <br />

Item <input type="text" onkeypress='validate(event)' name="qty2" value="0"/>
<input type="button" onclick="bump(2,1)" value="+"/>
<input type="button" onclick="bump(2,-1)" value="-"/>
<input type="checkbox" name="cb2" value="20.00"
onClick="TotalCheckedValues()"  />Service 2 (£20.00) <br />

Item <input type="text" onkeypress='validate(event)' name="qty3" value="0"/>
<input type="button" onclick="bump(3,1)" value="+"/>
<input type="button" onclick="bump(3,-1)" value="-"/>
<input type="checkbox" name="cb3" value="20.00"
onClick="TotalCheckedValues()" />Service 3 (£20.00) <br />

Item <input type="text" onkeypress='validate(event)' name="qty4" value="0"/>
<input type="button" onclick="bump(4,1)" value="+"/>
<input type="button" onclick="bump(4,-1)" value="-"/>
<input type="checkbox" name="cb4" value="10.00"
onClick="TotalCheckedValues()" />Service 4 (£10.00) <br />

Total: <input type="text" name="Total" readonly size="5" />

<input type="reset" name="reset" value="Clear Selected">

</form>

</body>
</html>

First, I'm not sure that's the kind of javascript from which you should learn... But, i'll try to give you some hints 首先,我不确定那是您应该从中学习的javascript。但是,我会尽力给您一些提示

There are 3 functions : validate , bump and TotalCheckedValues 有3个函数: validatebumpTotalCheckedValues

Validate is th easiest to understand. Validate是最容易理解的。 Note the call to this function in each onkeypress attribute. 注意每个onkeypress属性中对此函数的调用。 Validate is called to verify if the key that has just been pressed to type into the input is a number between 0 and 9 (included) or a dot. 调用Validate来验证刚刚按下以键入输入内容的键是0到9(包括)之间的数字还是点。 (the regex checks that) (正则表达式检查)

bump has been made to record the clicks on the + and - buttons on each item (to keep track of the quantity). bump以记录每个项目上+和-按钮的点击次数(以跟踪数量)。 It relies on the call to the document.items form that gives its items which are named by ascending order and are identified by the number in their names ( name="qty1" for the first item). 它依赖于对document.items表单的调用,该表单给出其items ,这些items按升序命名,并由其名称中的数字标识(第一个项目的name="qty1" )。 The function take as parameters the index of the item and the amount to increase or decrease its value ( bump(3,1) for the + button of the 3rd item which means : take the 3rd item and add 1 to its value ). 该函数将项目的索引以及增加或减少其值的数量作为参数bump(3,1)第3个项目的+按钮的bump(3,1)表示:取第3个项目并将其值加1)。 The function ends with a call to the 3rd function 该函数以对第三个函数的调用结束

TotalCheckedValues is there to recalculate the total amount ( sum(quantity*price) for each item if the checkbox is checked for this item ). TotalCheckedValues可以在其中重新计算总金额(如果选中了此项目的复选框,则为每个项目的sum(quantity*price) )。 This function retriver the items, iterate on these, check if the checkbox is checked and if so, take the price and the quantity, multiply them and add them to the total 此功能检索项目,对其进行迭代,检查复选框是否被选中,如果是,则取价格和数量,相乘并将其加到总计中

// Also going to be cleaning up the code a little - no offense, I'm just anal
// One more note: I'll be specifying types in my function documentation - but remember
// that JS doesn't really *do* types


/**
 * Grab a quantity and increase it by a given value
 * @param int which Number of the field to target (comes out as 'qty1/2/3/4/etc')
 * @param int bywhat Number to increase the value found with 'which' by
 */
function bump(which, bywhat) {
    // Find the form child named 'qtyn', where n is a number
    // Notice only one var definition here - no need to define form if 
    // you can just get to your target element/attribute/etc.
    var qty = document.items['qty' + which].value;

    qty = Number(qty) + bywhat; // Add bywhat to the form value
    TotalCheckedValues(); // in case user bumped an already checked line
}

/**
 * Iterate through all check boxes (cb) on the form and multiply quantities (qty)
 * against values on checked boxes.
 */
function TotalCheckedValues() {
    // Some consider it best practice to put all vars in the top of the method,
    // in a comma-separated list using one "var" keyword.
    var form = document.items,
        total = 0,
        checkbox = null,
        n = 1;

    for(n; n <= 4; ++n)
    {
        checkbox = "cb"+n; // make your code easier to read
        if(form[checkbox].checked) // if the checkbox of the item is ticked
        {
            // If the checkbox is checked, multiply it's value to that of each qty field
            total += form[checkbox].value * form["qty"+n].value;
        }
    }

    form.Total.value = total.toFixed(2); // Shorten 'total' to 2 decimal places
}

/**
 * Test for a valid key
 * @param event evt The key-related event
 */
function validate(evt) {
    /*
     * In javascript, the OR operator || is used as a way of setting defaults. So, 
     * keep trying values until one that's considered "true" is found:
     * var something = false;
     * var foo = null; 
     * var bar = 'abc';
     * var which = something || foo || bar; // value of 'which' is 'abc'
     */
    var theEvent = evt || window.event, 
        key = theEvent.keyCode || theEvent.which,
        regex = /[0-9]|\./; // Regex that matches 0-9 and '.'

    key = String.fromCharCode( key ); // Convert from key code to something usable

    // I almost think you could do... 
    // var ... key = String.fromCharCode(theEvent.keyCode || theEvent.which)
    // but I'm not sure.

    // If our key event's code doesn't pass our regex test
    if(!regex.test(key)) { 
        theEvent.returnValue = false;

        if(theEvent.preventDefault) 
            theEvent.preventDefault();
    }
}

Some Other Advice 其他建议

Some other pointers I'd like to share, perhaps just some suggestions to consider: 我想分享其他一些建议,也许只是一些建议可以考虑:

  • Relying on hardcoded limits (the '4' in the for loop in TotalCheckedValues()) makes your code less reusable. 依靠硬编码的限制(TotalCheckedValues()中for循环中的“ 4”)使代码的可重用性降低。 Instead, you should iterate over all matching children to the parent node. 相反,您应该将所有匹配的子代迭代到父节点。 With jQuery it'd be something like $('#MyFormId input[type="checkbox"]).each(...) This makes the code flexible and doesn't need updating just because you added another checkbox. 使用jQuery,它就像$('#MyFormId input[type="checkbox"]).each(...)这样的代码,它使代码变得灵活并且不需要更新,因为您添加了另一个复选框。

  • Use an ID on your form element to make selecting more obvious - relying on document[name] is ok but may not play well everywhere. 在表单元素上使用ID可以使选择更加明显-依靠document [name]是可以的,但可能并非在所有地方都能很好地发挥作用。

  • which , bywhat , evt - Variable names are great because they can be anything, so keep that in mind when deciding what to call your variables. 其中 ,bywhat,EVT -变量名是伟大的,因为他们可以是任何东西,所以决定要打电话给你的变量时,记住这一点。 Descriptive names 1) help you remember what's happening when you come back to the code 2 months later and 2) help anyone else who has to go through your code, for whatever reason, to understand what is happening. 描述性名称1)帮助您记住两个月后返回代码时发生的事情,以及2)帮助出于任何原因必须仔细阅读代码的其他人以了解发生了什么。

  • Consistency is key: Your function names are mixed in style: bumb vs TotalCheckedValues vs validate - you should pick one way for your code and stick to it. 一致性是关键:函数名混合使用: bumb vs TotalCheckedValues vs validate-您应该为代码选择一种方式并坚持下去。

  • Visit JSLint sometime if you really want something that will nitpick your code...and make you cry. 如果您确实想要一些东西可以窃取您的代码,并且让您哭泣,请随时访问JSLint。 But just reading the "How does JSLint work?" 但是只要阅读“ JSLint如何工作?”即可。 page about how and why they pick apart certain parts of your code can be valuable in learning Javascript and some of the Best Practices © for JS. 关于如何以及为什么它们将代码的某些部分分开的页面,对于学习Javascript和JS的一些最佳实践©而言非常有价值。

NOTE: I got about half way through writing this, and found people had already answered - apologies for any repetition but I wanted to finish what I started! 注意:撰写本文的过程已经差不多完成了一半,发现人们已经回答了。对于任何重复,我都表示歉意,但是我想完成我开始的工作!

1. The 'bump' function 1.“凹凸”功能

This function accepts two parameters: 此函数接受两个参数:

  • ' which ' is a number which helps to identify a particular text field. 哪个 ”是有助于识别特定文本字段的数字。
  • ' bywhat ' is a number indicating by how much the number in the field is to be increased/decreased - or to use the term used here - 'bumped'. bywhat ”是一个数字,指示字段中的数字要增加/减少多少(或使用此处使用的术语)“颠簸”。

var form = document.items; var form = document.items;

The function starts by getting an array all of the items in the global document object, which you can access from anywhere. 该函数首先获取全局文档对象中所有项目的数组,您可以从任何位置访问该数组。

var qty = form['qty' + which]; var qty = form ['qty'+ which];

This code then attempts to access a particular item in that array, which has a name of 'qty' plus the which argument. 此代码然后尝试该阵列,其具有“数量”加上参数的名称在访问特定项。 When you use the '+' operator in this case, where you're adding a string ('qty') to a number ( which ), you end up with a string; 在这种情况下,当您使用'+'运算符时,您要在数字( which )上添加一个字符串('qty'),最后会得到一个字符串。 eg 'qty3'. 例如“ qty3”。

qty.value = Number(qty.value) + bywhat; qty.value =数字(qty.value)+多少;

The value of the 'qty+ where ' input element is then set, by taking the current value, converting it to a number, and then adding the bywhat argument to it. 然后通过获取当前值,将其转换为数字,然后在其上添加bywhat参数,来设置输入元素“ qty + where ”的值。 When you use the '+' operator in this case, where you're adding a number to a number, you perform a mathematical calculation; 在这种情况下,当您使用'+'运算符时,您要将数字加到数字上,就需要进行数学计算; eg 1 + 2 = 3. 例如1 + 2 = 3。

TotalCheckedValues(); TotalCheckedValues();

The code then calls the TotalCheckedValues function, which appears to calculate the total (we'll come to that next). 然后,代码调用TotalCheckedValues函数,该函数似乎用于计算总数(我们将在下一部分介绍)。

2. The 'TotalCheckedValues' function 2.'TotalCheckedValues'函数

This function is called after by every 'bump' function call, and is also called every time a checkbox is checked/unchecked. 每次“凹凸”函数调用之后都会调用此函数,并且每次选中/取消选中复选框时也会调用此函数。

var form = document.items; var form = document.items;

The function again starts by getting an array all of the items in the global document object, which you can access from anywhere. 该函数再次从获取全局文档对象中所有项目的数组开始,您可以从任何位置访问该数组。

var total = 0; var total = 0;

The function then defines a 'total' variable, which is set to zero. 然后,该函数定义一个“总计”变量,该变量设置为零。

The 'for' loop “ for”循环

The code then loops four times, one time for each of the input/button/checkbox groups in the HTML. 然后,该代码循环四次,对于HTML中的每个输入/按钮/复选框组,循环一次。 It tries to get the checkbox element for each group, then checks to see if that checkbox is checked. 它尝试获取每个组的复选框元素,然后检查是否已选中该复选框。 If it is, the checkbox value (which is the price) is multiplied by the textfield's quantity value, and added to the 'total' variable. 如果是,则复选框值(即价格)乘以文本字段的数量值,然后添加到“总计”变量中。 The '+=' operator here adds the value on the right hand side of it to the existing value, rather than overwriting the existing value. 这里的“ + =”运算符将其右侧的值添加到现有值,而不是覆盖现有值。

form.Total.value = total.toFixed(2); form.Total.value = total.toFixed(2);

The function then attempts to find an element with the name 'Total' in the document.items array, using dot notation instead of the brackets notation you've seen before (form['qty'], for example). 然后,该函数尝试使用点符号而不是您之前看到的方括号符号(例如,form ['qty'])在document.items数组中查找名称为'Total'的元素。 The value of that element is set using the total generated by the for loop above. 使用上面的for循环生成的总数来设置该元素的值。 The toFixed(2) function can be used on numbers to return a string representation of the number with the given number of decimal places - in this case, 2. toFixed(2)函数可用于数字以返回具有给定小数位数的数字的字符串表示形式-在这种情况下为2。

3. The 'validate' function 3.“验证”功能

var theEvent = evt || var theEvent = evt || window.event; window.event;

Creates a variable containing the event object which has been raised. 创建一个包含已引发的事件对象的变量。 It checks if there is an event object in the passed evt argument - if it's null or undefined, it uses the window.event event object. 它检查传递的evt参数中是否有事件对象-如果它为null或未定义,则使用window.event事件对象。

var key = theEvent.keyCode || var key = theEvent.keyCode || theEvent.which; theEvent。哪个;

Tries to determine what key was pressed to trigger the event and stores it in a variable. 尝试确定按下了哪个键来触发事件并将其存储在变量中。

var regex = /[0-9]|./; var regex = /[0-9]|./;

Defines a regular expression pattern, which will match the values zero to nine, and the dot character. 定义一个正则表达式模式,它将匹配值零到九以及点字符。

key = String.fromCharCode(key); 键= String.fromCharCode(键);

Attempts to retrieve a character string from the key, which... 尝试从密钥中检索字符串,这会...

if(!regex.test(key)) if(!regex.test(key))

...is then tested against the regular expression. ...然后针对正则表达式进行测试。 The test() function returns true if it matches the pattern, false if it doesn't. 如果test()函数与模式匹配,则返回true;否则,返回false。 The rest of the code inside this 'if' statement is run if the regex match fails; 如果正则表达式匹配失败,则运行“ if”语句中的其余代码; it sets a return value for the event, and cancels the event (preventDefault) without stopping the propagation of the event to other listeners. 它设置事件的返回值,并取消事件(preventDefault),而不停止将事件传播到其他侦听器。

Hope that walkthrough of the JavaScript functions helps! 希望JavaScript函数演练对您有所帮助!

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

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