【问题标题】:Most efficient way to create an element from any jquery selector string从任何 jquery 选择器字符串创建元素的最有效方法
【发布时间】:2015-02-20 21:30:05
【问题描述】:

我需要做什么

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

快速示例。

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>

为什么

我有一些按钮,当点击它们时,它们会根据其数据属性执行不同的任务。 其中之一是data-target。我希望能够使用任何 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 的选择器引擎来执行此操作,因为再次分析选择器字符串并提取其属性似乎很冗长。

非常感谢

【问题讨论】:

  • 许多字符串只能用作选择器而不是创建器,因此使用 any 选择器实现您想要的效果是不现实的。
  • 您需要编写一个解析器,将a.exaggerated#selector[data-myattr='data-here'] 转换为&lt;a id="selector" class="exaggerated" data-myattr="data-here"&gt;&lt;/a&gt;。这基本上是将 Jade 之类的东西(不完全是)编译成 HTML。

标签: javascript jquery sizzle


【解决方案1】:

并非所有选择器都可以做到这一点,但如果您确定提供的选择器有效,我会从以下内容开始:

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;
}

【讨论】:

    【解决方案2】:

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

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

    jquery 2.1.1 及以上版本需要访问 $.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'));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      相关资源
      最近更新 更多