出于好奇,有可能重构这个:
document.querySelectorAll('input[id^=' + tagId + '],select[id^=' + tagId + '],textarea[id^=' + tagId + ']');
更小的东西,像这样?:
document.querySelectorAll('(input|select|textarea)[id^=' + tagId + ']');
当然这不起作用,这就是我要问的原因。 有可能吗?
答案 0 :(得分:2)
使用:any
伪类;
document.querySelectorAll('[id^=' + tagId + ']:-webkit-any(input, textarea, select)');
现在,您需要为Chrome和Safari添加-webkit-
前缀,或为Firefox添加-moz
;没有IE支持。这可能最终以名称:matches
标准化。请参阅MDN文档here。
然而,通过它们的ID管理DOM元素,就像它们在某个巨大的全局命名空间中被命名为变量一样,是一种反模式。很有可能有更好的方法来查找和跟踪元素,而不是在代码中分配一堆ID,然后在每次转身时都会getElementById
或等效,以便找到它再一次,更不用说做类似通配符的搜索了。
答案 1 :(得分:0)
您可以将"[id^=" + tagId + "]"
与:not(/* element */):not(/* element */)
var tagId = "abc";
var elems = document.querySelectorAll("[id^=" + tagId + "]:not(div):not(p)");
console.log(elems)
<input id="abc-1">
<select id="abc-2"></select>
<textarea id="abc-3"></textarea>
<div id="abc-4"></div>
<p id="abc-5"></p>
或者,您可以向className
,data-*
,input
元素添加select
或textarea
属性; data-*
属性不需要名称或值;仅用于选择过滤;然后,您可以使用document.querySelectorAll("[id^=" + tagId + "][data-_]");
或简短document.querySelectorAll("[data-_]")
var tagId = "abc";
var elems = document.querySelectorAll("[id^=" + tagId + "][data-_]");
console.log(elems, elems[0].dataset)
<input id="abc-1" data-_>
<select id="abc-2" data-_></select>
<textarea id="abc-3" data-_></textarea>
<div id="abc-4"></div>
<p id="abc-5"></p>
使用Array.prototype.filter()
的方法,虽然不如使用唯一className
或data-*
属性那么简短,类似于OP中描述的模式
var tagId = "abc";
var elems = [].filter.call(document.querySelectorAll("[id^=" + tagId + "]")
, function(el) {
return /input|select|textarea/i.test(el.tagName)
});
console.log(elems)
<input id="abc-1">
<select id="abc-2"></select>
<textarea id="abc-3"></textarea>
<div id="abc-4"></div>
<p id="abc-5"></p>
答案 2 :(得分:0)
在:any
选择器标准化之前,您可以使用辅助函数,类似于使用CSS预处理器(借用@guest271314's example):
function makeSelector(tagId, elements) {
return elements.map(function(el) {
return el + '[id^=' + tagId + ']';
}).join(',');
}
var selector = makeSelector('abc', ['input','select','textarea']);
console.log(document.querySelectorAll(selector));
<input id="abc-1">
<select id="abc-2"></select>
<textarea id="abc-3"></textarea>
<div id="abc-4"></div>
<p id="abc-5"></p>
然后,您可以在以后交换帮助程序实现(例如,使用:any
),而不会影响功能。
答案 3 :(得分:0)
通过使用document.body.style
处的功能检测,将document.querySelcectorAll()
扩展为在:any
内部添加供应商前缀而不在选择器字符串中包含供应商前缀的方法。可能会在几个方面得到改善;可以添加当前需要供应商前缀的其他css
选择器,多个if
语句可以更彻底或更短;和其他改进
originalQuerySelectorAll = document.querySelectorAll;
console.log(originalQuerySelectorAll);
document.querySelectorAll = function() {
var selector = arguments[0];
if (/\:any/.test(selector)) {
if ("webkitAnimation" in document.body.style) {
selector = selector.replace(/\:(any)/g, ":-webkit-$1");
}
if ("MozAnimation" in document.body.style) {
selector = selector.replace(/\:(any)/g, ":-moz-$1");
}
}
return originalQuerySelectorAll.call(document, selector)
}
var tagId = "abc";
var elems = document.querySelectorAll("[id^=" + tagId + "]:any(input, select, textarea)");
console.log(elems)
<input id="abc-1">
<select id="abc-2"></select>
<textarea id="abc-3"></textarea>
<div id="abc-4"></div>
<p id="abc-5"></p>
jsfiddle https://jsfiddle.net/0xpu1bvw/