CSS命名空间和重写jquery选择器

时间:2012-09-20 16:35:04

标签: jquery css jquery-selectors

我正在寻找覆盖基本jQuery选择器,以便任何jQuery选择器中的所有CSS类($('.classname')),包括.find(.classname).parents(.classname)等,都以'为前缀'命名空间”。在上面的示例中,我的jQuery代码看起来像$('.classname'),但是会被转换为$('.SomeCssNamespace_classname')

$('.classname')选择器匹配的HTML将如下所示:
    <div class="SomeCssNamespace_classname" />

最重要的是,我必须以regex的形式添加智能,这只能用于类名,而不是id或标签选择器。例如$('#someId')不会被翻译为$('#SomeCssNamespace_someId')

此外,必须覆盖jQuery.addClass()jQuery.removeClass()方法以添加相同的命名空间。

2 个答案:

答案 0 :(得分:2)

我的解决方案是编写自己的函数来执行此操作...例如:

prefixClassSelector = function(prefix,class_name) {
    return $('.' + prefix + '_' + class_name);
}

然后你可以像这样调用它,它仍然是可链接的

prefixClassSelector('someNamespace','myclass').hide();

答案 1 :(得分:0)

尝试这样的事情:

// define the namespace
jQuery.myjQueryNamespace = {

  name: 'custom_', // the prefix

  // returns the prefixed selector, classname needs to be prefixed with "."
  addNamespace: function(selector) {

    if (typeof String.prototype.indexOf == "function") {
      return selector.replace(/\./g, '.' + jQuery.myjQueryNamespace.name);
    } else {
      // TODO: write my own indexOf function
      return selector;
    }
  },

  // returns the prefixed selector, classname should *not* to be prefixed with "."
  prefixNamespace: function(selector) {
    return jQuery.myjQueryNamespace.name + 'selector';
  }
}

// keep the original init function
jQuery.fn._init = jQuery.fn.init;

jQuery.fn.init = function(selector, context, rootjQuery) {

  if (typeof selector == 'string'
  && typeof String.prototype.indexOf == "function" // assumes String.prototype.indexOf is defined
  && selector.indexOf('.') != -1) {

    var myNewSelector = jQuery.myjQueryNamespace.addNamespace(selector);
    return jQuery.fn._init.call(this, myNewSelector, context, rootjQuery);
  } else {

    return jQuery.fn._init.call(this, selector, context, rootjQuery)
  }
}

// *got this from the jQuery source code
jQuery.fn.init.prototype = jQuery.fn;

// modify addClass and removeClass
for (var fn_key in jQuery.fn) {

  // if the function has "Class" in it, replace the function
  if (fn_key == 'addClass' || fn_key == 'removeClass') {

    // we'll keep the original function prefixed with underscore
    jQuery.fn['_' + fn_key] = jQuery.fn[fn_key];

    // build the new function which calls the original function passing in the namespaced selector
    var new_function = new Function("selector", "return jQuery.fn['" + '_' + fn_key + "'].call(this, jQuery.myjQueryNamespace.prefixNamespace(selector));");

    // assign it to the original name
    jQuery.fn[fn_key] = new_function;
  }
}

警告:我只是通过粘贴到控制台进行测试,并且仅在chrome中进行测试。它可能有意想不到的行为。

最好在加载jquery后立即运行,允许其他插件被命名空间。

代码的作用是将jQuery.fn.init函数替换为类名前缀的修改版本。致电jQuery.fn.init时会运行$(selector)功能。我们以类似的方式修改addClassremoveClass