我正在尝试创建一个函数,每次运行时都会增加其参数。你总是可以手动重写函数,但我将多次运行这个函数,并希望能够方便地重用代码。
$("div").each(function() {
function rangeF(firstValue, increment) {
var first = firstValue + "-"; //Set the first value and put a hypen after it
firstValue += increment; //Increment it by the increment
var second = firstValue; //Set the second value
firstValue++; //Increment by one to avoid duplicates
return first + second; //return both values (e.g. 1-2 or x-y)
}
range = rangeF(5 , 10); //5 is the value to start on, 10 + 1 is the increment (need to access both 5 + 10 & 5 + 11)
range2 = rangeF(2, 2); //2 is the value to start on, 2 + 1 is the increment (need to access both 2 + 2 & 2 + 3)
$(this)
.append('<div>' + range + '</div>')
.append('<div>' + range2 + '</div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#1 range: <div></div>
<br />
#2 range: <div></div>
<br />
#3 range: <div></div>
现在,它显示:
#1 range:
P 5-15
P 2-4
#2 range:
P 5-15
P 2-4
#3 range:
P 5-15
P 2-4
我想展示:
#1 range:
P 5-15
P 2-4
#2 range:
P 16-26
P 5-7
#3 range:
P 27-37
P 8-10
以最干净,可重复使用的方式。
提前致谢。
更新对于这种混乱感到抱歉,但我的意思是我不想重复使用全局变量来解决问题...再次感谢您的所有贡献。
答案 0 :(得分:2)
我建议用工厂解决这个问题:
// jQuery plugin named rangify
$.fn.rangify = function rangify(ranges) {
// factory to generate auto-incrementers
function rangeFactory(value, increment) {
// scoped variables `value` and `increment`
// re-used by inner function
// this is essentially the same
// function as in original question
return function range() {
var first = value;
value += increment;
var second = value;
value++;
return 'P ' + first + '-' + second;
}
}
// when jQuery plugin is called
// this initializes scoped auto-incrementers
// with arguments supplied from array of tuples
var calls = ranges.map(function map(args) {
return rangeFactory(args[0], args[1]);
});
// iterate through context of jQuery selector
return this.each(function each() {
// reference to single element in jQuery selector
var $this = $(this);
// for each auto-incrementer
calls.forEach(function (call) {
// append the generated range
$this.append('<div>' + call() + '</div>');
});
});
};
// tell plugin to generate
// 1. sequential ranges of 10 starting at 5
// 2. sequential ranges of 2 starting at 2
$("div").rangify([[5, 10], [2, 2]]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#1 range: <div></div>
<br />
#2 range: <div></div>
<br />
#3 range: <div></div>
&#13;
我为你写了一个jQuery插件,它使用工厂存储范围变量来代替你试图避免的全局变量。
我刚刚创建了一个更通用的插件,您可以在其中指定给定参数返回的内容,以及每次如何增加参数:
// jQuery plugin named rangify
$.fn.rangify = function rangify(getter, increment, tuples) {
// decorator to transform getter into auto-incrementing getter
function decorator(tuple) {
// scoped variable `tuple`
// re-used by decorated function
return function decorated() {
// get content from getter
var content = getter.apply(undefined, tuple);
// increment the arguments for the getter
tuple = increment.apply(undefined, tuple);
// return the content
return content;
}
}
// when jQuery plugin is called
// this initializes scoped auto-incrementers
// with arguments supplied from array of tuples
var calls = tuples.map(decorator);
// iterate through context of jQuery selector
return this.each(function each() {
// reference to single element in jQuery selector
var $this = $(this);
// for each auto-incrementer
calls.forEach(function (call) {
// append the generated content
$this.append(call());
});
});
};
// you supply the following functions to the plugin
// return content
function content(value, increment) {
var first = value;
var second = value + increment;
return '<div>P ' + first + '-' + second + '</div>';
}
// return incremented arguments
function increment(value, increment) {
value += increment + 1;
return arguments;
}
// tell plugin to generate content
$("div").rangify(content, increment, [[5, 10], [2, 2]]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#1 range: <div></div>
<br />
#2 range: <div></div>
<br />
#3 range: <div></div>
&#13;
要说明这是通用的原因,请考虑以下示例:
// jQuery plugin named rangify
$.fn.rangify = function rangify(getter, increment, tuples) {
// decorator to transform getter into auto-incrementing getter
function decorator(tuple) {
// scoped variable `tuple`
// re-used by decorated function
return function decorated() {
// get content from getter
var content = getter.apply(undefined, tuple);
// increment the arguments for the getter
tuple = increment.apply(undefined, tuple);
// return the content
return content;
}
}
// when jQuery plugin is called
// this initializes scoped auto-incrementers
// with arguments supplied from array of tuples
var calls = tuples.map(decorator);
// iterate through context of jQuery selector
return this.each(function each() {
// reference to single element in jQuery selector
var $this = $(this);
// for each auto-incrementer
calls.forEach(function (call) {
// append the generated content
$this.append(call());
});
});
};
// you supply the following functions to the plugin
// return content
function content(className, chapter, section) {
return '<div class="' + className + '">Chapter ' + chapter + ' - Section ' + section + '</div>';
}
// return incremented arguments
function increment(className, chapter, section) {
if (section === 'C') {
section = 'A';
chapter++;
} else {
var nextCode = section.charCodeAt(0) + 1;
section = String.fromCharCode(nextCode);
}
return arguments;
}
// tell plugin to generate content
$("div").rangify(content, increment, [['red', 1, 'A'], ['green', 4, 'A']]);
&#13;
div:not([class]) {
display: inline-block;
border: 1px solid black;
padding: 5px;
margin-bottom: 5px;
}
.red {
color: red;
}
.green {
color: green;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
&#13;
答案 1 :(得分:1)
不确定这是否是你所追求的问题是不明确的,但是这会将参数注入到装饰函数中,这将增加装饰函数的每次调用。
计数器在incrementRangeDecorator
函数的关闭中保留,因此它不会暴露于全局范围。
// function decorator that will inject two argements into the
// decorated function that will be incremented each call
const incrementRangeDecorator = function(start, increment, fn) {
return function(...args) {
const ret = fn(start, start += increment, ...args)
start = start + 1
return ret
}
}
// function to decorate
function rangeF(start, current, extraArg) {
console.log('called rangeF()', `${start}-${current}`, extraArg)
}
// decorate rangeF with the incrementRangeDecorator
const incrementBy2 = incrementRangeDecorator(2, 2, rangeF)
const incrementBy5 = incrementRangeDecorator(5, 10, rangeF)
incrementBy2('you')
incrementBy2('can')
incrementBy2('pass')
incrementBy5('extra')
incrementBy5('arguments')
incrementBy5()
&#13;
答案 2 :(得分:0)
使用
$(function() {
});
将等待执行,直到DOM准备就绪。 (这相当于.ready()函数,甚至建议使用而不是.ready()...)
里面的变量不是'全局',它们属于那个函数。
其余的解释了自己。
$(function() {
var a = 5; var b = 10; var c = 2; var d = 2;
$("div").each(function() {
function rangeF(firstValue, increment) {
var first = firstValue + "-"; //Set the first value and put a hypen after it
firstValue += increment; //Increment it by the increment
var second = firstValue; //Set the second value
firstValue++; //Increment by one to avoid duplicates
return first + second; //return both values (e.g. 1-2 or x-y)
}
range = rangeF(a, b);
range2 = rangeF(c, d);
a = a+b+1;
c = c+d+1;
$(this)
.append('<div>' + range + '</div>')
.append('<div>' + range2 + '</div>');
});
});
div {
border:#999 1px solid;
padding:1em;
margin:1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="A">
</div>
<div id="B">
</div>
<div id="C">
</div>
希望它有所帮助。