是否可以将选项列表分为两部分(列)?例如,一个选项的文本位于左侧,另一个位于右侧,但位于同一行。
示例:
+--------------------select options-----------------------+
option1 option text for text1
option2 option text for text1
+---------------------------------------------------------+
答案 0 :(得分:0)
我找到了解决这个问题的方法。它不会像你想要的那样完美,但我认为它应该适合你。
它有点棘手,也很长。我发布了一个jsfiddle文件:*http://jsfiddle.net/7c5qr0h9/8/*
(我使用*来符合答案的资格)
也许这将是结果的一种方式。看看吧!
答案 1 :(得分:0)
虽然我建议使用样式化的<ul>
或<ol>
来使用JavaScript和CSS执行此操作,但使用JavaScript执行此操作是可能的 - 尽管不一定可靠或漂亮。但是,没有方法可以使用本机HTML或CSS执行此操作,特别是因为<option>
元素不能包含子节点,这意味着CSS无法定位或分离,使用padding
或text-align
或任何其他方式的各列。
然而,使用JavaScript,一种方法如下;在这里我扩展了HTMLSelectElement
的原型,这意味着它被用作该元素类型的方法,如果这个方法没有在注释中充分记录,那么这可以被认为是有问题的,如果你有任何,不要意外地遇到或覆盖它。尽管如此,我确实认为这是一种方便,但是我会在这个答案后面提供一种更“实用”(可能是“微创”)的方法。也就是说,这是我的答案的第一次迭代(代码的解释在代码的注释中):
HTMLSelectElement.prototype.optionColumnize = function(opts) {
// caching a reference to the 'this' Node, which will be
// (barring binding/applying etc) a <select> element:
var select = this,
// caching the options of the <select> element, using
// Function.prototype.call() and Array.prototype.slice()
// to create an Array of those options (rather than a
// NodeList/collection:
options = Array.prototype.slice.call(select.options, 0),
// iterating over the Array of <option> elements in
// in order to find the <option> with the most
// text, using Array.prototype.reduce() to compare
// the length of the current <option> against the
// previous <option>, and retaining the <option>
// with the greatest length:
greatestOption = options.reduce(function(a, b) {
return a.text.length > b.text.length ? a : b;
}),
// initialising the default settings of the method:
s = {
// String: defining the character which should
// separate the columns:
'separator': '/',
// Number or String: defining the character-length
// of the between 'column' spacing (whatever
// argument is given will be passed to parseInt()
// prior to use):
'paddingLength': 5,
// String: characters from which the padding string
// will be created; this string will be repeated
// by the 'paddingLength' (above) variable:
'paddingString': ' '
};
// iterating over the user-supplied opts Object to employ
// user-defined settings:
for (var prop in opts) {
// if the opts Object has property set by the user
// (ie not a property inherited from its prototype
// chain):
if (opts.hasOwnProperty(prop)) {
// we set the property of the default
// settings Object ('s') to be equal to
// that set in the opts Object:
s[prop] = opts[prop];
}
}
// splitting the columns of the greatestOption (found above)
// into an Array by splitting the string of text by the
// character supplied by the s.separator setting:
var greatestOptionColumns = greatestOption.text.split(s.separator),
// finding the integer represented by the s.paddingLength
// property, converting the value into a base-10 number:
paddingLength = parseInt(s.paddingLength, 10),
// creating two variables (currently undefined) to be
// used within the loop (below):
columns,
textDelta;
// iterating over each of the <option> elements held in the
// options Array, using Array.prototype.forEach() to do so:
options.forEach(function(opt) {
// the first argument of the anonymous function,
// (here 'opt') is the current array-element of
// the array over which we're iterating.
// splitting the text of the current <option> of
// the options Array by the supplied string held
// in the s.separator property, this returns an
// array over which we iterate with the
// Array.prototype.map() function to return a new
// Array to the 'columns' variable:
columns = opt.text.split(s.separator).map(function(col, index, allCols) {
// 'col': the current element of the created array,
// index: the index of the current array-element,
// allCols: the full array.
// if the current array-element is less than the
// length of the Array - 1 (Length is one-based,
// JavaScript Arrays have zero-based indexing):
if (index < allCols.length - 1) {
// we find the difference between the text-length
// of the current element and the element of the
// same index in the greatestOptionColumns Array:
textDelta = greatestOptionColumns[index].length - col.length;
// here we return the current array-element + the padding string,
// created via String.prototype.repeat(), which is chained to
// a String ('s.paddingString') and a numeric argument
// ('paddingLength + textDelta') to create a new String
// of 's.paddingString' by the number of times supplied as
// the numeric argument ('n'.repeat(3) -> 'nnn'):
return col + s.paddingString.repeat(paddingLength + textDelta);
// otherwise (if we are the last array-element of the
// current array
} else {
// we simply return the existing array-element
// so we don't have any 'trailing' padding:
return col;
}
});
// setting the innerHTML of the current <option> element
// to the contents of the columns Array, using
// Array.prototype.join() to join the elements together
// with an empty-string:
opt.innerHTML = columns.join('');
});
};
// calling the function with no arguments:
document.getElementById('demo1').optionColumnize();
// calling the function, and changing the padding-length to 10:
document.getElementById('demo2').optionColumnize({
'paddingLength': 10
});
// calling the function, and changing the padding-String to '~':
document.getElementById('demo3').optionColumnize({
'paddingString': '~'
});
// calling the function, and changing the column-separator to 'o':
document.getElementById('demo4').optionColumnize({
'separator': 'o'
});
// calling the function, and changing:
// - column-separator to 'n',
// - padding-length to 7,
// - padding-string to '+'
document.getElementById('demo5').optionColumnize({
'separator': 'n',
'paddingLength': '7',
'paddingString': '+'
});
select {
display: block;
margin: 0 0 1em 0;
}
<select id="demo1">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo2">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo3">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo4">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo5">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
外部JS Fiddle demo用于实验或开发。
当然,对上述内容的另一种看法是将其用作“常规”函数,而不是HTMLSelectElement
的方法;如此使用它我们必须将相关的节点传递给函数,并且 - 理想情况下,但不是强制性地&amp; ndash检查提供的节点是否为<select>
元素。为此,略微改变以上内容如下:
function optionColumnize(el, opts) {
// caching a reference to the Node upon which we're working,
// and ensuring it's a select element (otherwise we return
// from the function):
if (el.tagName.toLowerCase() === 'select') {
var select = el;
} else {
return false;
}
// caching the options of the <select> element, using
// Function.prototype.call() and Array.prototype.slice()
// to create an Array of those options (rather than a
// NodeList/collection:
options = Array.prototype.slice.call(select.options, 0),
// iterating over the Array of <option> elements in
// in order to find the <option> with the most
// text, using Array.prototype.reduce() to compare
// the length of the current <option> against the
// previous <option>, and retaining the <option>
// with the greatest length:
greatestOption = options.reduce(function(a, b) {
return a.text.length > b.text.length ? a : b;
}),
// initialising the default settings of the method:
s = {
// String: defining the character which should
// separate the columns:
'separator': '/',
// Number or String: defining the character-length
// of the between 'column' spacing (whatever
// argument is given will be passed to parseInt()
// prior to use):
'paddingLength': 5,
// String: characters from which the padding string
// will be created; this string will be repeated
// by the 'paddingLength' (above) variable:
'paddingString': ' '
};
// iterating over the user-supplied opts Object to employ
// user-defined settings:
for (var prop in opts) {
// if the opts Object has property set by the user
// (ie not a property inherited from its prototype
// chain):
if (opts.hasOwnProperty(prop)) {
// we set the property of the default
// settings Object ('s') to be equal to
// that set in the opts Object:
s[prop] = opts[prop];
}
}
// splitting the columns of the greatestOption (found above)
// into an Array by splitting the string of text by the
// character supplied by the s.separator setting:
var greatestOptionColumns = greatestOption.text.split(s.separator),
// finding the integer represented by the s.paddingLength
// property, converting the value into a base-10 number:
paddingLength = parseInt(s.paddingLength, 10),
// creating two variables (currently undefined) to be
// used within the loop (below):
columns,
textDelta;
// iterating over each of the <option> elements held in the
// options Array, using Array.prototype.forEach() to do so:
options.forEach(function(opt) {
// the first argument of the anonymous function,
// (here 'opt') is the current array-element of
// the array over which we're iterating.
// splitting the text of the current <option> of
// the options Array by the supplied string held
// in the s.separator property, this returns an
// array over which we iterate with the
// Array.prototype.map() function to return a new
// Array to the 'columns' variable:
columns = opt.text.split(s.separator).map(function(col, index, allCols) {
// 'col': the current element of the created array,
// index: the index of the current array-element,
// allCols: the full array.
// if the current array-element is less than the
// length of the Array - 1 (Length is one-based,
// JavaScript Arrays have zero-based indexing):
if (index < allCols.length - 1) {
// we find the difference between the text-length
// of the current element and the element of the
// same index in the greatestOptionColumns Array:
textDelta = greatestOptionColumns[index].length - col.length;
// here we return the current array-element + the padding string,
// created via String.prototype.repeat(), which is chained to
// a String ('s.paddingString') and a numeric argument
// ('paddingLength + textDelta') to create a new String
// of 's.paddingString' by the number of times supplied as
// the numeric argument ('n'.repeat(3) -> 'nnn'):
return col + s.paddingString.repeat(paddingLength + textDelta);
// otherwise (if we are the last array-element of the
// current array
} else {
// we simply return the existing array-element
// so we don't have any 'trailing' padding:
return col;
}
});
// setting the innerHTML of the current <option> element
// to the contents of the columns Array, using
// Array.prototype.join() to join the elements together
// with an empty-string:
opt.innerHTML = columns.join('');
});
};
// calling the function with no arguments:
optionColumnize(document.getElementById('demo1'));
// calling the function, and changing the padding-length to 10:
optionColumnize(document.getElementById('demo2'), {
'paddingLength': 10
});
// calling the function, and changing the padding-String to '~':
optionColumnize(document.getElementById('demo3'), {
'paddingString': '~'
});
// calling the function, and changing the separator to 'o':
optionColumnize(document.getElementById('demo4'), {
'separator': 'o'
});
// calling the function, and changing:
// - column-separator to 'n',
// - padding-length to 7,
// - padding-string to '+'
optionColumnize(document.getElementById('demo5'), {
'separator': 'n',
'paddingLength': '7',
'paddingString': '+'
});
select {
display: block;
margin: 0 0 1em 0;
}
<select id="demo1">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo2">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo3">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo4">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
<select id="demo5">
<option value="1">option 1/value 1/column3</option>
<option value="2">option 2/value 2/column3</option>
<option value="3">option 3/value 3/column3</option>
<option value="4">option 4/value 4/column3</option>
<option value="5">option 5/value 5/column3</option>
<option value="6">option 6/value 6/column3</option>
<option value="7">option 7/value 7/column3</option>
<option value="8">option 8/value 8/column3</option>
<option value="9">option 9/value 9/column3</option>
<option value="10">option 10/value 9/column3</option>
</select>
外部JS Fiddle demo用于实验或开发。
参考文献:
Array.prototype.forEach()
。Array.prototype.join()
。Array.prototype.map()
。Array.prototype.reduce()
。Array.prototype.slice()
。Element.tagName
。Function.prototype.call()
。HTMLOptionElement
。HTMLSelectElement
。Object.prototype.hasOwnProperty()
。String.prototype.repeat()
。String.prototype.split()
。String.prototype.toLowerCase()
。