Reputation: 3364
I am using bootstrap and I looked into its jQuery plugin bootstrap-alert.js
and I couldn't quite get it.The code is posted below:
!function( $ ){
"use strict"
/* ALERT CLASS DEFINITION
* ====================== */
var dismiss = '[data-dismiss="alert"]'
, Alert = function ( el ) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype = {
constructor: Alert
, close: function ( e ) {
var $this = $(this)
, selector = $this.attr('data-target')
, $parent
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
}
$parent = $(selector)
$parent.trigger('close')
e && e.preventDefault()
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
$parent.removeClass('in')
function removeElement() {
$parent.remove()
$parent.trigger('closed')
}
$.support.transition && $parent.hasClass('fade') ?
$parent.on($.support.transition.end, removeElement) :
removeElement()
}
}
/* ALERT PLUGIN DEFINITION
* ======================= */
$.fn.alert = function ( option ) {
return this.each(function () {
var $this = $(this)
, data = $this.data('alert')
if (!data) $this.data('alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
/* ALERT DATA-API
* ============== */
$(function () {
$('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
})
}( window.jQuery )
This is pretty much the easiest one among all the plugins given.What I don't understand is
1.what's the selector
?The data-target
is nowhere to find...So,what $this.attr('data-target')
do?
2.How this plugin works as a whole?As the document says,it has three parts,how it interacts with each other?
EDIT: There is also something I don't quite understand.This part:
functionremoveElement() {
$parent.remove()
$parent.trigger('closed')
}
First you remove the element,then somehow you call a function which is not defined at all using some object which is removed already.Where is closed
?
Thanks,G
Upvotes: 4
Views: 8098
Reputation: 7180
I had the same problem and I set up a sample to play with.
I moved it to GitHub: https://github.com/MikeMitterer/jQPlayGround/ (with screenshot)
Source is documented - if you want, play with it. (means use the developer-tools to debug the code)
JS-Source: https://github.com/MikeMitterer/jQPlayGround/blob/master/assets/js/sample.js
More infos about Google-Chrome-Developer-Tools: http://code.google.com/chrome/devtools/docs/overview.html
Upvotes: 0
Reputation: 38410
First off, I'm no expert in jQuery plugins, plus the coding style is IMHO not very readable. Additionally I'm not sure if I understand what exactly you are asking, but I'll try to answer nevertheless.
data-target
seems to be an undocumented attribute on the close button/link. It allows you to select an element, that is acting as an alert, other than the parent of the clsoe button/link to be closed.
An example: Normally you would write the HTML for an alert like this:
<div class="alert">
<a class="close" data-dismiss="alert">×</a>
Some message
</div>
The last part ("Alert Data-API") assigns a click event to the close link, which triggers the Alert.prototype.close
function (without actually initiating an instance of the Alert
class).
In that function, first $this.attr('data-target')
is used to check if the close button has a data-target
attribute. If not then it uses a possible URL hash segment in the href
attribute as an ID selector. In this example, there is neither, so in the line
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
the close button's parent is selected as the alert to close.
If you however wanted the close button to be outside the alert, you'd use the data-target
or href
attributes:
<div id="my-alert" class="alert">
Some message
</div>
<!-- ... -->
<a class="close" data-dismiss="alert" href="#my-alert">Close "my-alert"</a>
<!-- ... -->
<a class="close" data-dismiss="alert" data-target=".alert">Close all "alerts" with the class "alert"</a>
About the functionality as a whole:
Despite being short it's unfortunately quite complicated. I'll try and explain it briefly:
As mentioned above: The last part places an click event handler on any alert close buttons defined by having the attribute data-dismiss="alert"
. It uses the Alert.prototype.close
function as the event handler without actually initiating an instance of the Alert
class.
The second part ("Plugin definition") defines the $().alert()
jQuery plugin. It doesn't do much, just creates an instance of the Alert and if the argument (option
) of the plugin is "close" it will call the close
method. Creating the instance on it's own is a bit pointless. The only reason for this is to match the pattern of the other plugins.
The first part defines the class Alert
, which as only one task: Close (remove) an element (the "alert") on the click of another element (the "close button").
One thing you have to understand is that. "Alerts" are nothing special. They could be any kind of HTML element with no special requirements. You explicitly "declare" an element as an alert by calling $().alert()
on it, but that isn't needed. Instead you could directly call $().alert("close")
on it when you want to close an element using script, or define a close button with data-dismiss="alert"
, which then closes any element it points to using data-target
, its href
or by being the child of the alert.
EDIT: (Sorry, didn't get around earlier)
if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 }
If the attribute data-target
wasn't set (or was empty), then the script attempts to use the href
attribute as the selector. The syntax of the "hash" part of an URL is the same as an CSS id selector, so it can used as the selector. The IE7 part is because even if the attribute only contains the hash part, the browser still returns the complete URL.
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
Yes, this could be written as
if (!$parent.length) {
// ...
}
I don't know why they chose this syntax. IMHO it's unnecessary cryptic and thus unreadable.
If you had href="#"
, then this line would lead it to be ignored, because $("#")
won't return any results ($parent.length
would be 0) and choose either itself (if it has the class alert
) or the parent of the element as the alert that is to be closed.
Upvotes: 5