Javascript 动态修改元素,使其与给定选择器匹配
假设我有这样的元素:Javascript 动态修改元素,使其与给定选择器匹配,javascript,jquery,css,jquery-selectors,css-selectors,Javascript,Jquery,Css,Jquery Selectors,Css Selectors,假设我有这样的元素: <div class="some-class"></div> 我想让我的div与这个选择器匹配。这需要 添加idmydiv 添加类super,另一个类 使用值true添加属性某些属性 所以最后一个div看起来像 <div class="some-class super another-class" id="mydiv" some-attribute="true"></div> 这将解析选择器并为任何有效选择器执行上面
<div class="some-class"></div>
我想让我的div与这个选择器匹配。这需要
- 添加id
mydiv
- 添加类
,super
另一个类
- 使用值
true添加属性
某些属性
<div class="some-class super another-class" id="mydiv" some-attribute="true"></div>
这将解析选择器并为任何有效选择器执行上面列出的步骤
我知道我可以做一些函数来解析选择器并执行它,但选择器可能非常复杂,同一个选择器可能以多种不同的方式组成,因此我决定尝试找到一些可靠的现有解决方案
你知道这样的事吗,或者有没有什么土生土长的方法
编辑:根据评论,我将尝试用不同的方式解释我的问题 问题的要点是: 是否可以用javascript解析任何有效的选择器,以了解它指向什么id、什么类和什么属性 所以我们想要
var selectorData = parseSelector('#my-id.class-one.class-two[attr-one="value-one"]');
selectorData.id //my-id
selectorData.classes //class-one class-two
selectorData.attributes["attr-one"] //value
因为有了关于选择器的这些数据,很容易使任何元素与之匹配。希望它能起作用
$(".some-class").addClass('super');
$(".some-class").addClass('another-class');
$(".some-class").attr('id','myDiv');
$(".some-class").attr('some-attribute',true);
我已经为此编写了一个小jquery函数
$.fn.makeMatch = function(ids, classes, attr) {
this.attr('id', ids).addClass(classes).attr(attr);
return this;
}
您现在只需:
$('div').makeMatch('firstComesOneId', 'then classes seperated by space', {'data-arrayKey1' : 'value1', 'data-arrayKey2' : 'value2'})
这将产生:
<div id="firstComesOneId" class="then classes seperated by space" data-arrayKey1="value1" data-arrayKey2="value2">
花了我一些时间,我真的希望这有帮助:)
问候timmi一种可能的方法,尽管有点幼稚,是:
// create a jQuery plug-in, 'makeMatch()' and pass a selector
// string as an argument:
(function ($) {
$.fn.makeMatch = function (selector) {
// finding a string of one or more alphanumeric characters,
// underscores and hyphens that starts with the '#' character,
// using String.prototype.match() with a regular expression:
var id = selector.match(/#[\w-]+/),
// similar to the above, though this string starts with a
// period (escaped with a back-slash because the period
// is a special character in regular expressions), using
// the 'g' (global) flag to retrieve all matching
// sequences:
classes = selector.match(/\.[\w-]+/g),
// this string looks for strings starting with a '['
// (again escaped because it's a special character) and
// continuing until it matches a character that is *not*
// ']':
attributeValuePairs = selector.match(/\[[^\]]+/g);
// if we have an 'id' sequence:
if (id) {
// assigning the found id sequence to the id variable
// (preventing us from accessing a property of a null
// object) after replacing the leading '#' character
// with an empty string:
id = id[0].replace(/^#/,'');
}
// iterating over the passed-in jQuery object, 'this' (here)
// is the collection of nodes:
return this.each(function () {
// caching the current node found in the collection:
var self = this;
// if we have an id (it's not null):
if (id) {
// setting the id to that matched-id:
self.id = id;
}
// if we have an array of classes:
if (classes) {
// adding the classes from the array, by joining
// each class-string together with spaces and replacing
// the period characters (though we could simply do:
// classes.replace(/\./g,' ') instead):
$(self).addClass(classes.join(' ').replace(/\./g, ''));
}
if (attributeValuePairs) {
// creating a variable to avoid re-initialising a
// variable within the forEach():
var av;
attributeValuePairs.forEach(function(avp) {
// replacing the initial '[' character from
// each element of the array with an empty string
// and splitting that string on the '=' character
// to form a two-part array (if a '=' character
// is found):
av = avp.replace(/^\[/, '').split('=');
// if we do have a two-part array:
if (av.length === 2) {
// setting the attribute held in 'av[0]' with
// the value held in 'av[1]' (after replacing
// any quotes held in that string):
self.setAttribute(av[0], av[1].replace(/"|'/g, ''));
}
});
}
});
};
})(jQuery);
(函数($){
$.fn.makeMatch=函数(选择器){
var id=selector.match(/#[\w-]+/),
classes=selector.match(/\.[\w-]+/g),
attributeValuePairs=selector.match(/\[^\]]+/g);
如果(id){
id=id[0]。替换(/^#/,“”);
}
返回此值。每个(函数(){
var self=这个;
如果(id){
self.id=id;
}
if(类){
$(self).addClass(classes.join('').replace(/\./g');
}
if(属性值对){
var-av;
attributeValuePairs.forEach(函数(avp){
av=avp.replace(/^\[/,'').split('=');
如果(平均长度===2){
self.setAttribute(av[0],av[1]。替换(/“|'”/g',);
}
});
}
});
};
})(jQuery);
$(“.some class”).makeMatch(“#mydiv.super.other class[some attribute=“true”]”);
div{
边框:1px实心#000;
宽度:200px;
高度:200px;
}
#另一个类[some attribute=“true”]{
边框:2倍纯红;
背景:透明url(http://lorempixel.com/200/200/nightlife)50%50%不重复;
}
您误解了我的问题。它确实会使元素与选择器匹配,但您所做的是-您已经用大脑将选择器解析为重要元素,在您的头脑中,您知道需要什么id、类和属性,并且您已经编写了反映这一点的代码。我希望计算机能够这样做。因此,我只告诉选择器和元素,以及javascript将完成其余的工作。因此,如果元素有数据属性或id,您希望得到它吗?我也没有完全得到您想要的…例如,您有一个带有一些属性和类的div。现在您希望在jquery中从该div中获得所有类和属性?正确吗?您希望使用新选择器创建一个CSS规则-可能与.some class
选择器-显示元素现在将匹配此选择器。我理解要点和意图,但我真的不想这么做…;)在这种情况下,拥有一个可运行的代码段似乎是多余的:)@BoltClock:是的,出于某种原因,我觉得您在代码段中指的是插件应该添加选择器(不,我不知道为什么会这样想).编辑并添加。这是一个非常有趣的用例,虽然不太清楚。选择器确实很复杂,但您尝试执行的操作的性质会产生一些有趣的限制,以便缩小潜在解决方案的范围。例如,仅功能选择器(类型、ID、类和属性)虽然可能需要编写一个完整的解析器,但精确的实现可能有点广泛,即使解析器仅限于处理一个只包含特征选择器的复合选择器。
<div id="firstComesOneId" class="then classes seperated by space" data-arrayKey1="value1" data-arrayKey2="value2">
$.fn.stringToObject = function(values) {
var selectorData = [];
var start_posID = values.indexOf('#') + 1;
var end_posID = values.indexOf('.',start_posID);
selectorData['id'] = values.substring(start_posID,end_posID);
var classSplit = values.split('.');
var classLength = classSplit.length -1;
var attrSplit = values.match(/\[/g);
var attrLength = attrSplit.length;
var start_posClass = end_posID;
var end_posClass = values.indexOf('[',start_posClass);
var stringClass = values.substring(start_posClass, end_posClass);
selectorData['classes'] = stringClass.replace(/\./g, " ");
for (var i = 0; i <= attrLength; i++) {
if (i == 0) {
var start = values.indexOf('[') + 1;
} else if(i == attrLength) {
start = nextstart -1;
} else {
start = nextstart +2;
}
var end = values.indexOf(']',start);
var newstring = values.substring(start, end);
var nextstart = end;
var newstringLength = newstring.length;
var firstPartOffset = newstring.indexOf('=');
var firstPart = newstring.substring(0, firstPartOffset);
var secondPart = newstring.substring(firstPartOffset +1, newstringLength);
selectorData[firstPart] = secondPart;
};
return selectorData;
}
var valueArray = $( "div" ).stringToObject('#mydiv.super.another-class[some-attribute1="true"][some-attribute2="truesdsda"][some-attribute3="trueasd"][some-attribute4="true"][some-attribute5="truedfg"]');
console.log(valueArray); // gives you everything
console.log(valueArray.id); // = gives you the id
console.log(valueArray.classes); // = gives you the classes
console.log(valueArray['some-attribute5']); // = gives you the value from some-attribute5
// create a jQuery plug-in, 'makeMatch()' and pass a selector
// string as an argument:
(function ($) {
$.fn.makeMatch = function (selector) {
// finding a string of one or more alphanumeric characters,
// underscores and hyphens that starts with the '#' character,
// using String.prototype.match() with a regular expression:
var id = selector.match(/#[\w-]+/),
// similar to the above, though this string starts with a
// period (escaped with a back-slash because the period
// is a special character in regular expressions), using
// the 'g' (global) flag to retrieve all matching
// sequences:
classes = selector.match(/\.[\w-]+/g),
// this string looks for strings starting with a '['
// (again escaped because it's a special character) and
// continuing until it matches a character that is *not*
// ']':
attributeValuePairs = selector.match(/\[[^\]]+/g);
// if we have an 'id' sequence:
if (id) {
// assigning the found id sequence to the id variable
// (preventing us from accessing a property of a null
// object) after replacing the leading '#' character
// with an empty string:
id = id[0].replace(/^#/,'');
}
// iterating over the passed-in jQuery object, 'this' (here)
// is the collection of nodes:
return this.each(function () {
// caching the current node found in the collection:
var self = this;
// if we have an id (it's not null):
if (id) {
// setting the id to that matched-id:
self.id = id;
}
// if we have an array of classes:
if (classes) {
// adding the classes from the array, by joining
// each class-string together with spaces and replacing
// the period characters (though we could simply do:
// classes.replace(/\./g,' ') instead):
$(self).addClass(classes.join(' ').replace(/\./g, ''));
}
if (attributeValuePairs) {
// creating a variable to avoid re-initialising a
// variable within the forEach():
var av;
attributeValuePairs.forEach(function(avp) {
// replacing the initial '[' character from
// each element of the array with an empty string
// and splitting that string on the '=' character
// to form a two-part array (if a '=' character
// is found):
av = avp.replace(/^\[/, '').split('=');
// if we do have a two-part array:
if (av.length === 2) {
// setting the attribute held in 'av[0]' with
// the value held in 'av[1]' (after replacing
// any quotes held in that string):
self.setAttribute(av[0], av[1].replace(/"|'/g, ''));
}
});
}
});
};
})(jQuery);