【问题标题】:queryselector get elements where attribute starts with 'xxx'queryselector 获取属性以“xxx”开头的元素
【发布时间】:2020-10-30 01:38:10
【问题描述】:

我正在尝试获取属性以comp- 开头的所有项目。所以,把这个html作为参考:

<h1 comp-Color="red">Hello, world!</h1>
<h1 comp-Background="black">Hello, world!</h1>
<h1 comp-Age="123">Hello, world!</h1>

我试过这样做,但它似乎不起作用:

let e = document.querySelectorAll('[^comp-]');

这样做会给我以下错误:

未捕获的 DOMException:无法在“文档”上执行“querySelectorAll”:“[^comp-]”不是有效的选择器。

【问题讨论】:

  • 没有部分属性选择器
  • 属性名称或任何属性值? xpath或许可以做到
  • @JaromandaX 属性名称是我想要得到的。

标签: javascript


【解决方案1】:

你可以使用 xpath 来完成这样的任务

例如要获取以xxx- 开头的所有属性,请使用 xpath 字符串

'//*/attribute::*[starts-with(name(), "xxx-")]'

或者,attribute:: 的简写是 @ - 这就是上述情况

'//*/@*[starts-with(name(), "xxx-")]'

快速示例代码

var nodesSnapshot = document.evaluate('//*/attribute::*[starts-with(name(), "xxx-")]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var attr;
for (var i=0; i < nodesSnapshot.snapshotLength; i++ ) {
   attr = nodesSnapshot.snapshotItem(i);
   console.log(attr, attr.ownerElement) 
});

延伸阅读:XPATH on MDN

我还没有找到更详细文档的可靠来源。 document.evaluate 在除 IE 之外的所有浏览器中都可用,但是,我记得有一个用于 IE 的 xpath 库 - 不确定它有多完整

google wicked good xpath

基于

javascript-xpath

【讨论】:

  • 这看起来像是在做我想做的事!让我弄乱一下
【解决方案2】:

按照@wordSmith,您可以执行以下操作:

document.querySelectorAll("#selectId option[value*='G-']");

这意味着all options inside #selectId with a value that starts with 'G-'

【讨论】:

  • 不,不是那个意思。 “*”表示 包含 字符串中的任何位置,而不是开头。为此使用“^”。
【解决方案3】:

我认为您可以使用[xxx*],这就是我和其他许多人信任的这个惊人的资源所说的:https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048 在第 12 号。

【讨论】:

  • 我不认为这适用于 JavaScript,因为我得到了同样的错误
【解决方案4】:

很遗憾,querySelectorAll 不支持分词。但是,有一个库 dom-regex(免责声明:我写的),就是这样做的。

它允许您使用正则表达式查询 DOM。你可以随心所欲地宽松或严格。

查询整个 DOM:

// Get all elements that have `comp-xxx="` in their opening tag
let e = DomRegex.all(/ comp-\w+="/i);

更便宜:

您可以提供一个选择器或一组元素来查询,而不是查询整个 DOM:

let e = DomRegex.all.against('h1', / comp-\w+="/i);

工作示例:

// Just include DomRegex here as a 1 liner:
!function(r,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("DomRegex",[],t):"object"==typeof exports?exports.DomRegex=t():r.DomRegex=t()}(this,function(){return function(r){function t(e){if(n[e])return n[e].exports;var o=n[e]={exports:{},id:e,loaded:!1};return r[e].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=r,t.c=n,t.p="",t(0)}([function(r,t,n){"use strict";function e(r){return"HTMLElement"in window?r&&r instanceof HTMLElement:!(!r||"object"!==("undefined"==typeof r?"undefined":d(r))||1!==r.nodeType||!r.nodeName)}function o(r){if(r instanceof RegExp)return!0;throw new TypeError("The regex parameter must be a Regular Expression")}function i(r){if(!r||"string"==typeof r)return!0;throw new TypeError("The attr parameter must be a non-empty String")}function u(r){if(e(r))return[r];if(r instanceof NodeList&&(r=Array.from(r)),Array.isArray(r))return r.filter(e);if(""!==r&&("string"==typeof r||r instanceof String))return Array.from(document.querySelectorAll(r));throw new TypeError("The first param should be a selectorOrDomNode")}function f(r){return r.outerHTML.match(/^<((?:[^>"]+|"[^"]*")+)>/)[1]}function a(r,t,n){var e=n?r.getAttribute(n):f(r);return t.test(e)}function c(r){return r?"filter":"find"}function l(r,t,n){o(t),i(n);var e=c(r);return Array.from(document.querySelectorAll("*"))[e](function(r){return a(r,t,n)})}function p(r,t,n,e){var f=u(t);o(n),i(e);var l=c(r);return f.map(function(r){return Array.from(r.querySelectorAll("*"))}).reduce(function(r,t){return r.concat(t)},[])[l](function(r){return a(r,n,e)})}function y(r,t,n,e){var f=u(t);o(n),i(e);var l=c(r);return f[l](function(r){return a(r,n,e)})}Object.defineProperty(t,"__esModule",{value:!0});var d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r};n(1),n(2);var s={all:function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return l.apply(void 0,[!0].concat(t))},one:function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return l.apply(void 0,[!1].concat(t))}};s.all.inside=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return p.apply(void 0,[!0].concat(t))},s.all.against=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return y.apply(void 0,[!0].concat(t))},s.one.inside=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return p.apply(void 0,[!1].concat(t))||null},s.one.against=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];return y.apply(void 0,[!1].concat(t))||null},t.default=s,r.exports=t.default},function(r,t){"use strict";!function(){Array.prototype.find||(Array.prototype.find=function(r){if(null==this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof r)throw new TypeError("predicate must be a function");for(var t,n=Object(this),e=n.length>>>0,o=arguments[1],i=0;i<e;i++)if(t=n[i],r.call(o,t,i,n))return t})}()},function(r,t){"use strict";Array.from||(Array.from=function(){var r=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===r.call(t)},n=function(r){var t=Number(r);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t},e=Math.pow(2,53)-1,o=function(r){var t=n(r);return Math.min(Math.max(t,0),e)};return function(r){var n=this,e=Object(r);if(null==r)throw new TypeError("Array.from requires an array-like object - not null or undefined");var i,u=arguments.length>1?arguments[1]:void 0;if("undefined"!=typeof u){if(!t(u))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(i=arguments[2])}for(var f,a=o(e.length),c=t(n)?Object(new n(a)):new Array(a),l=0;l<a;)f=e[l],u?c[l]="undefined"==typeof i?u(f,l):u.call(i,f,l):c[l]=f,l+=1;return c.length=a,c}}())}])});

// Get all elements that have `comp-xxx="` in their opening tag
let e = DomRegex.all.against('h1', / comp-\w+="/i);
console.log(e);
<h1 comp-Color="red">Hello, world!</h1>
<h1 comp-Background="black">Hello, world!</h1>
<h1 comp-Age="123">Hello, world!</h1>
<h1>Hello World!</h1>

【讨论】:

    【解决方案5】:

    试试这个:

    let e = document.querySelectorAll("[id^='comp-']");
    

    自从我误读了问题后,这不起作用。

    编辑

    那么让我建议一下:

    var allH1 = document.querySelectorAll("h1");
    [].forEach.call(allH1, function(d) {
        var a = [].filter.call(d.attributes, function(at) { return /^comp-/.test(at.name); });
        var attrName = a[0].name;
        var attrValue = a[0].value;
    });
    

    【讨论】:

    • 我没有id 属性
    • 如果您直接过滤 allH1,您将返回属性以 comp Array.from(allH1).filter(el =&gt; Array.from(el.attributes).some(a =&gt; a.name.match(/^comp/))) 开头的节点
    猜你喜欢
    • 2016-12-04
    • 1970-01-01
    • 2020-12-18
    • 2017-04-10
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多