从任何jquery选择器字符串创建元素的最有效方法

Most efficient way to create an element from any jquery selector string

本文关键字:有效 方法 元素 创建 任何 jquery 选择器 字符串      更新时间:2024-01-26

我需要做什么

我想创建一个匹配任何选择器字符串的元素

快速示例

var targetString = "a.exaggerated#selector[data-myattr='data-here']";
var targetEl = $(targetString);
if(!targetEl.length){
    var newEl = //create target
    $(body).append(newEl);
}

输出

<body>
    <a class="exaggerated" id="selector" data-myattr="date-here"></a>
</body>

为什么

我有一些按钮,点击后会根据其数据属性执行不同的任务。其中之一是CCD_ 1。我希望能够使用ANY-sizzlejs/jquery选择器作为目标,如果dom中不存在目标元素,则创建它。例如

<button data-create-target="true" data-target=".mytarget">clickme</button> <button data-create-target="true" data-target="a.[data-type='popup']">clickme</button>


我希望有一种方法可以使用jquery的选择器引擎来实现这一点,因为再次分析选择器字符串并提取其属性似乎很冗长。

非常感谢

这不是所有选择器都可以实现的,但如果您确信所提供的选择器可以工作,我会从以下内容开始:

function createElement(selector) {
    var element = document.createElement('div');
    if (/^[a-z][a-z0-9'-]*/.test(selector)) {
        element = document.createElement(selector.match(/^[a-z][a-z0-9'-]*/)[0]);
    }
    // Wrap in jquery
    element = $(element);
    // Find the classes
    if (/'.([a-z][a-z0-9'-]*)/g.test(selector)) {
        selector.match(/'.([a-z][a-z0-9'-]*)/g).forEach(function (class) {
            element.addClass(class.substr(1));
        });
    }
    // Find the id
    if (/#([a-z][a-z0-9'-]*)/.test(selector)) {
        element.attr('id', selector.match(/#([a-z][a-z0-9'-]*)/)[0]);
    }
    // Find the attributes
    if (/'[([a-z][a-z0-9'-]*)=''(.+)''']/) {
        var match = /'[([a-z][a-z0-9'-]*)=''(.+)''']/.exec(selector);
        element.attr(match[1], match[2]);
    }
    return element;
}

我创建了一个插件来解决这个问题。

$("a.exaggerated#selector[data-myattr='data-here']").create().appendTo('body');

jquery 2.1.1版和obove需要访问$.find.tokenize方法

$.fn.create = function( elem, dataAndEvents, deepDataAndEvents ) { 
    if(this.length){
        return $(this).clone( elem, dataAndEvents, deepDataAndEvents );
    } else {
    var selector = this.selector;
        var rquickExpr = /^(?:#(['w-]+)|('w+)|'.(['w-]+))$/;
        var match, elem, m;
        if(!selector){
            return $(document.createElement('div'));
        } 
        if(match = rquickExpr.exec( selector )){
            if ( match[2] ) {
                return $(document.createElement(selector));
            } else {
                var elem = document.createElement('div');
                if ( (m = match[1]) ) {             
                    elem.id = m;            
                } else if ( (m = match[3])) {
                    elem.className = m ; 
                }
                return $(elem);
            }
        }
        selector = selector.replace( rtrim, "$1" );
        match = $.find.tokenize(selector);
        if ( match.length === 1 ) {
            var attrs = '';
            var tag = 'div';
            var classList = [];
            var type, value, matches;
            var tokens = match[0] = match[0].slice( 0 );
            for (var i = 0; i < tokens.length; i++) {
                type = tokens[i].type;
                value = tokens[i].value
                matches = tokens[i].matches;
                if ( type === "ID" ){
                    attrs += 'id="' + matches[0] + '" ';
                    continue;
                }
                else if ( type === "CLASS" ){
                    classList.push(matches[0]+matches[1]+matches[2]);
                    continue;
                }
                else if ( type === "TAG" ){
                    tag = matches[0];
                    continue;
                }
                else if ( type === "ATTR" ){
                    attrs += matches[0]+ (matches[1] ? matches[1] : '' ) + (matches[2] ? '"' + matches[2] + '"': '' )+ ' ';
                }
                else if ( type === "PSEUDO" ){
                }
                else if ( type === "CHILD" ){
                } 
            };
            if(classList.length){
                attrs += 'class="';
                for (var i = 0; i < classList.length; i++) {
                     attrs +=  classList[i] + ' ';
                };
                attrs += '"';
            }
            return $('<' + tag + ' ' + attrs + '></' + tag + '>');
        }
        return $(document.createElement('div'));
    }
}