有三个字段的数字从1到3.我试图这样做,如果一个人只使用箭头,那么应该总是一个“1”,一个“2”和一个“3”。为什么它不总是有效,我怎么能让它起作用呢?
jQuery(document).ready(function($) {
var prevNumber;
$(".numbers").focus(function() {
prevNumber = $(this).val();
}).change(function() {
curNumber = $(this).val();
$('.numbers[value="' + curNumber + '"]:not(:focus)').first().val(prevNumber);
prevNumber = curNumber;
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
这是jsfiddle。
答案 0 :(得分:6)
value
属性未连接到输入值。我知道这听起来令人惊讶。 :-) value
属性是输入的默认值。它不会更改(除非您使用setAttribute("value", x);
或.defaultValue = x;
进行更改)。
您的选择器使用属性:
$('.numbers[value="' + curNumber + '"]')...
因此,它将适用于输入,其值未被用户更改,但一旦输入就会失败,选择错误的输入。
您可以通过同时设置defaultValue
和value
来更改默认值和值(确保同时更新已更改的defaultValue
),就像这样(见评论):
jQuery(document).ready(function($) {
var prevNumber;
$(".numbers").focus(function() {
prevNumber = $(this).val();
}).change(function() {
// Get the element wrapper
var $this = $(this);
// Get the current value
var curNumber = $this.val();
// Make sure the default value on this element is updated
this.defaultValue = curNumber;
// Update both the value and default value on the other
// input that used to have this number
$('.numbers[value="' + curNumber + '"]:not(:focus)').first().val(prevNumber).prop("defaultValue", prevNumber);
prevNumber = curNumber;
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
我想我会在不试图记住状态的情况下接近它,例如,仅在change
:获取更改的数字,然后将任何其他数字分配给其兄弟姐妹。见评论:
var numbers = $(".numbers").map(function() { return this.value; }).get();
jQuery(document).ready(function($) {
$(".numbers").change(function() {
// Get a wrapper for this input
var $this = $(this);
// Get this number
var thisNumber = $this.val();
// Get the unused numbers
var unused = numbers.filter(function(num) { return num != thisNumber; });
// Assign them to the siblings, in order
$this.siblings().val(function(index) {
return unused[index];
});
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
我保留了一般性,而不是假设值只有1,2和3(而不是假设只有三个数字)。
答案 1 :(得分:2)
代码中的问题是“value”属性包含输入的初始值。使用以下选择器时:
$('.numbers[value="' + curNumber + '"]:not(:focus)')
您正在选择最初具有给定值的元素,而现在没有此值。 请尝试使用此选择器,一切正常:
$('.numbers:not(:focus)').filter(function(index, element){
return $(element).val() == curNumber;
})
这是jsfiddle。 ;)
答案 2 :(得分:1)
我想为您提供一个更精细的解决方案,可以在您的应用程序增长时帮助您:您应该将JS值存储在控制它的<input />
之外(这样,添加多个{{1或者修改代码中的值变得更容易。最重要的是你应该有一个独立于DOM的单个可信数据存储,它总是处于有效状态(在这种情况下:没有重复)。
鉴于你的问题(值应该是唯一的,只有交换应该是可能的),它更容易处理它作为纯JS问题(并且不要尝试在jQuery中做所有事情 - 虽然我同意它&# 39;一个伟大的lib,它不一定是所有东西的最佳工具。)
以下是我评论的解决方案:
<input>
&#13;
jQuery(document).ready(function($) {
// This array the current values of the inputs
var numbers = [1, 2, 3];
// numbers should not be modified directly but trough
// setNumber: this function ensures that numbers is ALWAYS
// a swap of the original value ([1, 2, 3]).
// When a value is set, this function returns the previous
// index of the value
function setNumber(index, newVal) {
// find other index
var prevIndex = numbers.indexOf(newVal);
if (prevIndex < 0) {
alert('Invalid value, please enter 1, 2 or 3');
}
// swap
numbers[prevIndex] = numbers[index];
numbers[index] = newVal;
return prevIndex;
}
// This function updates the inputs to ensure
// that their displayed value match the one stored in numbers
function updateNumbersView() {
$(".numbers").each(function(idx, elem) {
elem = $(elem);
if (parseInt(elem.val(), 10) !== numbers[idx]) {
elem.val(numbers[idx]);
}
});
}
$(".numbers").change(function() {
var self = $(this);
var curNumber = parseInt(self.val(), 10);
var curIndex = $(".numbers").index(self);
if (curNumber === numbers[curIndex]) {
return false; // no change
}
// update model:
var changedIndex = setNumber(curIndex, curNumber);
// updateView:
$('.numbers').eq(changedIndex).val(numbers[changedIndex]);
// or to be more generic (ie. multiple inputs for the same value):
// updateNumbersView();
});
});
&#13;
答案 3 :(得分:1)
我会通过向每个节点添加另一个属性来解决这个问题。
jQuery(document).ready(function($) {
var $numbers = $('.numbers'),
off = false;
$numbers.each(function () {
this.prev = this.value;
});
$numbers.change(function () {
var source = this;
if (off) return; // this algorithm is already running
off = true;
$numbers.each(function () {
if (this !== source && this.value === source.value) { // if conflict
this.prev = this.value = source.prev; // swap with old value
}
});
this.prev = this.value; // update for next time
off = false; // re-enable
});
});
&#13;
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;