私は最初の jQuery プラグインを作成しており、多少機能する例 ( http://tapmeister.com/test/selector.htmlを参照) とスクリプトを以下に示します。要素の配置に何日も苦労しています。
目的の外観と機能は、テキストとオプションの下向き矢印をテキストの右側に表示することから始まります。クリックすると、テキスト/矢印がオプションのリストに置き換えられ、現在選択されているオプションが強調表示され、元のテキストと同じ場所に配置されます。オプションをクリックすると、そのオプションが現在選択されているオプションになり、ユーザー定義のコールバックが開始されます。その他のスペースをクリックすると、ダイアログが閉じます。
プラグインは元の select 要素を置き換えます。インラインかブロックかを保持したいと考えています。ただし、それらをインラインにすると、 position:absolute<ul class="selectIt-list">
ポップアップは関連付けられたテキストの上に表示されません<span class="selectIt-text">
。span テキストと ul popup の両方が position:relative<div class="selectIt">
にあるのに、なぜ左端にあるのでしょうか?
補足として、私がこれを行っている主な理由は、プラグインの構築方法に関する一貫したパターンを学ぶことです。私は自分のアプローチをhttp://docs.jquery.com/Plugins/Authoringに強く基づいています(そうすべきでない理由はありますか?)。誰かがそれをレビューし、プラグインの構築方法を正しく解釈しているかどうかを確認し、提案を提供してくれることを願っています. また、名前空間全体を本当に取得できるかどうかもわかりません。これを別の質問として投稿する必要があるかもしれませんが、コードの批評を求めることが適切かどうかはわかりません。
ありがとう!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>Testing</title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<style type="text/css">
/* CSS associated with plugin */
div.selectIt {
position:relative;
}
span.selectIt-text {
color: #2C46B7;
cursor: pointer;
font-family: Verdana;
font-size: 10px;
display:inline;
}
span.selectIt-text,
ul.selectIt-list {
padding: 7px 3px 5px;
}
ul.selectIt-list {
display:none;
margin:0px;
position: absolute;
background-color: #FFFFFF;
border: 1px solid #B3B4A7;
z-index: 50;
box-shadow: 3px 1px 6px #505050;
}
ul.selectIt-list li {
background-color: #FFFFFF;
color: #393926;
list-style-type: none;
font-family: Verdana;
font-size: 10px;
margin-bottom: 2px;
padding-left: 2px;
padding-right: 2px;
}
ul.selectIt-list li.selectIt-hover {
background-color: #DFDED8;
color: #393926;
}
ul.selectIt-list li.selectIt-selected {
background-color: #737060;
color: #FFFFFF;
cursor: default;
}
/* CSS Not associated with plugin */
ul.myList > li {
list-style-type: none;
display:inline;
}
#horizontalList select.mySelect {
display:inline;
}
#verticalList select.mySelect {
display:block;
}
span.label {
color: rgb(57, 57, 38);
font-family: Verdana;
font-size: 10px;
font-weight: bold;
}
span.selectIt-text {
background-image: url("dropdown_arrow_blue.gif");
background-position:right center;
background-repeat: no-repeat;
padding-right: 10px; /*Override padding-right to allow for image*/
}
</style>
<script>
/*
* jQuery SelectIT
* Copyright 2012 Michael Reed
* Dual licensed under the MIT and GPL licenses.
*
*/
(function( $ ){
var methods = {
init : function( options ) {
//console.log('init');
// Create some defaults, extending them with any options that were provided
var settings = $.extend({
'class' : null, //Applies custom class so user may override
'extraWidth' : 0, //Extra space to add to width to allow for user image css
'click' : function(){} //Some user defined code.
}, options || {}); //Just in case user doesn't provide options
//Apply events that should only happen once (unlike what is done by http://docs.jquery.com/Plugins/Authoring#Events. Why did they do it that way?)
$(document).on('click.selectIt',methods.close);
return this.each(function(){
var $t = $(this),
data = $t.data('selectIt');
//Replace element
var list = $('<ul/>', {'class': "selectIt-list" }),
length,
max=0;
$t.find('option').each(function(i){
var $this=$(this),
text=$this.text(),
length = parseInt($this.css('width'));
max = length > max ? length : max;
list.append( $('<li/>', {text: text}))
});
max=max+settings.extraWidth;
list.css('width',max+'px');
var selectIt = $('<div/>', {class:"selectIt"+((settings.class)?' '+settings.class:'')}) //Didn't work to display same as original element: display:$t.css('display')
.append($('<span/>', {class:'selectIt-text',text:$t.find(":selected").text()}))
.append(list)
.css({display:$t.css('display')}); //Set to same as original element
//Apply events
selectIt.on('click.selectIt','span.selectIt-text',methods.open);
selectIt.on('mouseenter.selectIt','ul.selectIt-list li',methods.mouseenter);
selectIt.on('mouseleave.selectIt','ul.selectIt-list li',methods.mouseleave);
selectIt.on('click.selectIt','ul.selectIt-list li',methods.click);
// If the plugin hasn't been initialized yet. Why?
if ( ! data ) {
// Do more setup stuff here
$t.data('selectIt', {
target : $t, //Not really sure where this will be used
selectIt : selectIt, //Will be used when removing in destroy method
settings: settings //Save here so other methods have access
});
}
$t.hide().after(selectIt);
});
},
destroy : function(e) {
//console.log('destroy');
return this.each(function(){
var $t = $(this);
$t.off('.selectIt'); //Removes any events in selectIt namespace
$t.data('selectIt').selectIt.remove(); //Removes element from page
$t.removeData('selectIt'); //Removes data in selectIt namespace
//Should the original element be made visible?
})
},
open : function(e) {
//console.log('open');
methods.close();
var $t=$(this),
$p=$t.parent(),
index=$p.prev().prop("selectedIndex"),
list=$p.find('ul.selectIt-list').show();
list.find('li.selectIt-selected').removeClass('selectIt-selected');
list.find('li').eq(index).addClass('selectIt-selected');
var top = 0 - list.find('li').eq(index).position().top;
list.css({top: top});
e.stopPropagation(); //Don't trigger documents click
},
//If this is all I am doing, can change to just using CSS psudo class.
mouseenter : function(e) {
$(this).addClass('selectIt-hover');
},
mouseleave : function(e) {
$(this).removeClass('selectIt-hover');
},
click : function(e) {
//console.log('click');
var $t=$(this);
if(!$t.hasClass('selectIt-selected'))
{
var $p=$t.parent(),
$pp=$p.parent(),
select=$pp.prev(),
index=$t.index(),
option=select.find('option').eq(index),
value=(value=option.val())?value:option.text();
select.val(value).prop('selectedIndex',index);
$pp.find('span.selectIt-text').text($t.text());
select.data('selectIt').settings.click.call(this,value);
}
},
close : function(e) {
//console.log('close');
$('div.selectIt').find('ul.selectIt-list').hide().parent();//.find('span.selectIt-text').show();
},
update : function(content) {alert('When will this type of method be used?');}
};
$.fn.selectIt = function(method) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.selectIt' );
}
};
})( jQuery );
$(function(){
$('select.mySelect').selectIt({
//'class' : 'whatever',
'extraWidth' : 0,
'click':function(value){
switch(value)
{
case 'first':console.log('Do something first');break;
case 'second':console.log('Do something second');break;
case 'third':console.log('Do something third');break;
default: console.log('Do something default');
}
}
});
$('#horizontalList button.destroy').click(function(){
$('#horizontalList select.mySelect').selectIt('destroy');
});
$('#verticalList button.destroy').click(function(){
$('#verticalList select.mySelect').selectIt('destroy');
});
});
</script>
</head>
<body>
<div id="horizontalList">
<h1>Horizontal List</h1>
<ul class="myList">
<li>
<span class="label">Label</span>
<select class="mySelect">
<option value="first">First</option>
<option value="second" selected="selected">Second</option>
<option>Third</option>
</select>
</li>
<li>
<span class="label">Some Label</span>
<select class="mySelect">
<option value="first">First</option>
<option value="second" selected="selected">Second</option>
<option value="third">Third</option>
</select>
</li>
<li>
<span class="label">Some Label</span>
<select class="mySelect">
<option value="">First</option>
<option value="second">Second</option>
<option value="third">Third</option>
</select>
</li>
</ul>
<button class="destroy">Destroy</button>
</div>
<div id="verticalList">
<h1>Vertical List</h1>
<ul class="myList">
<li>
<span class="label">Label</span>
<select class="mySelect">
<option value="first">First</option>
<option value="second" selected="selected">Second</option>
<option>Third</option>
</select>
</li>
<li>
<span class="label">Some Label</span>
<select class="mySelect">
<option value="first">First</option>
<option value="second" selected="selected">Second</option>
<option value="third">Third</option>
</select>
</li>
<li>
<span class="label">Some Label</span>
<select class="mySelect">
<option value="">First</option>
<option value="second">Second</option>
<option value="third">Third</option>
</select>
</li>
</ul>
<button class="destroy">Destroy</button>
</div>
</body>
</html>