经过几个小时的努力,我已经解决了这个问题。事实证明,如果选项卡在获得焦点后即被按下,即没有在其中键入任何内容时,select2 AJAX 控件确实会破坏选项卡顺序。但是,如果键入了某些文本,它不会破坏制表符顺序。
select2 自动生成的 HTML 内部结构如下:
<div class="select2-container">
<a class="select2-choice">
<span</span>
<abbr class="select2-search-choice-close" />
<div> <b></b> </div>
</a>
<div class="select2-drop select2-offscreen">
<div class="select2-search">
<input class="select2-input select2-focused" tabIndex=<somevalue> />
</div>
<ul class="select2-results></ul>
</div>
</div>
如果在 HTML 选择控件中键入了一些文本,则制表符顺序正常工作,如果没有输入文本,则制表符顺序被破坏。在这两种情况下,我都document.activeElement
在 firebug 中使用过集中控制。在没有文本的情况下,锚元素具有焦点,而在输入文本的情况下,HTML 输入元素具有焦点。
如上所示,虽然select2.js
正确设置了 HTML 输入元素的 tabIndex 属性,但它没有设置锚元素。
解决方案
只需在下面进一步指定的位置添加以下行select2.js
:
this.container.find("a.select2-choice").attr("tabIndex", this.opts.element.attr("tabIndex"));
在后面添加一行:
this.opts.element.data("select2", this).hide().after(this.container);
this.container.data("select2", this);
this.dropdown = this.container.find(".select2-drop");
this.dropdown.css(evaluate(opts.dropdownCss));
this.dropdown.addClass(evaluate(opts.dropdownCssClass));
this.dropdown.data("select2", this);
this.results = results = this.container.find(resultsSelector);
this.search = search = this.container.find("input.select2-input");
之前:
search.attr("tabIndex", this.opts.element.attr("tabIndex"));
this.resultsPage = 0;
this.context = null;
// initialize the container
this.initContainer();
this.initContainerWidth();
installFilteredMouseMove(this.results);
this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
installDebouncedScroll(80, this.results);
this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
所以它变成:
this.results = results = this.container.find(resultsSelector);
this.search = search = this.container.find("input.select2-input");
this.container.find("a.select2-choice").attr("tabIndex", this.opts.element.attr("tabIndex")); /* atif */
search.attr("tabIndex", this.opts.element.attr("tabIndex"));
this.resultsPage = 0;
this.context = null;
在 中进行此更改select2.js
。显然,你需要使用完整的js版本,而不是min版本。
您所要做的就是添加一行,如上所述。如果正确完成,这将成为 VS2008 中的第 #504 行。