class Sqimitive.jQuery
extends Sqimitive.Base Sqimitive.jQuery.MixIn
Defined in: jquery.js, line 59
Modifiers: static
Holds reference to the global $
object.
var body = Sqimitive.jQuery.$('body')
var p = Sqimitive.jQuery.$('<p class=text>')
A similar global property Sqimitive._
holds reference to the
utility library in use.
Defined in: jquery.js, line 132 • Show code
$: $,
Modifiers: protected
from settable
May be set upon declaration via Core::extend() or mixIn and/or read/written directly on run-time.
Specifies if attach() should call attach()
on _children when it
changed the parent of el.
According to default Sqimitive’s lifecycle (see render), jQuery’s attach() propagates recursively while render() happens only when explicitly called. This is because attach() is fairly fast and often nearly no-op while render() may repopulate the entire el.
If your application’s lifecycle is different, use _invokeAttach to
disable the inherited attach() propagation without overriding =attach
entirely.
Defined in: jquery.js, line 259 • Show code
_invokeAttach: true,
Modifiers: protected
New standard options (Base._opt):
Name | Types | Notes |
---|---|---|
attachPath | string selector, object DOM or jQuery | Default root to
where this el is appended, resolved via _parent’s $() or, if
there’s no parent, via global $() . Used when attach() is called
without arguments (happens when _parent’s attach() or render() is
called).Usually the value is a string selector like |
el | false | There is no such option but if el is
given to new as part of options then it replaces the
declaration-time value of the el property – see el for details. |
string | ||
object |
Defined in: jquery.js, line 182 • Show code
_opt: {},
Modifiers: protected
from settable
May be set upon declaration via Core::extend() or mixIn and/or read/written directly on run-time.
Specifies if el should be jq:remove()’d from DOM when this sqimitive is remove()’d.
If disabled, remove() only unbinds elEvents and other listeners from
el but doesn’t notify _children so their nodes and listeners remain
unchanged, nor does it empty()
el’s contents produced by render()
or children.
Use _removeEl when you need special behaviour in remove() but don’t
want to override it entirely (=remove
) in order to keep jQuery’s
behaviour.
Defined in: jquery.js, line 274 • Show code
_removeEl: true,
from setOnDecl
May only be set upon declaration via Core::extend() or mixIn.
Holds a DOM node assigned to this object or null
.
// Set this.el by selector; becomes $(document.body):
new Sqimitive.jQuery({el: 'body'})
// Set this.el to a jQuery node:
new Sqimitive.jQuery({el: $('body')})
// Set this.el by a DOM node; becomes wrapped into $() by init():
new Sqimitive.jQuery({el: document.body})
// Create new element via string specification for $():
new Sqimitive.jQuery({el: '<p class=text>'})
// Create new element <p class="text"> by object:
new Sqimitive.jQuery({el: {tag: 'p', className: 'text'}})
// Cancel node creation, el becomes null:
new Sqimitive.jQuery({el: false})
// WRONG: when changing after construction el must always be a
// jQuery node, only and ever:
sqim.el = '<p class=text>'
// WRONG: result is a DOM node, not a jQuery node:
sqim.el = document.createElement('p')
// CORRECT: result is a jQuery node:
sqim.el = $('<p class=text>')
el’s value is special during construction: first, init()
takes the
value of either the el
key from new
’s options
or, if missing, of
this property, then sets el’s property value according to it:
Name | Types | Notes |
---|---|---|
false | Assumes null el; no DOM node is created or assigned -
useful for pure data structures aka “models” (but then you might not
need Sqimitive\jQuery at all, use the lighter Base). | |
string | A se #lec > .tor (errors if no node matched) or a <new
node=spec> as handled by the global $() | |
object | that passes is$() or canWrap() | Assumes this ready-made DOM or jQuery node. |
object | other | Creates a new DOM node with these HTML attributes and
calls el.data('sqimitive', this) . Special keys: tag (defaults to
div ) and className (overrides class unless falsy to work around
the reserved word).
|
In any case, el after init()
is either null
or a jQuery node with a
non-zero length
.
el is not automatically attached anywhere after construction, nor are
its elEvents bound – call attach() for this. Base.render() also
calls attach() but it does nothing if the attachPath
_opt’ion is
not set.
This property is not advised to change directly after init()
but if you
do then only set it to an is$()
object.
See Views overview (vw) for the high-level idea.
Defined in: jquery.js, line 184
from baseElEvents
from setOnDecl
May only be set upon declaration via Core::extend() or mixIn.
Declares event listeners for el, bound automatically by attach().
Types | Notes |
---|---|
object {event: func} |
elEvents’ format is consistent among Base’s subclasses and follows
Backbone’s bb:Model-events: keys are event references of form
event[.ns][ .sel #ector]
and values are strings (expandFunc()) or
functions, called as function (nativeEventObject)
(see argDanger).
from inMergeProps
This property is listed in _mergeProps by default so subclass defining it adds to its parent’s object instead of overwriting it entirely (but identical keys are still overwritten).
The .ns
part is ignored but can be used to create unique keys for the
purpose of inheritance. By convention, the class’ own handlers don’t have
ns
while handlers of mixIn-s do.
from es6thiswarn
Warning: avoid using ES6 arrow functions as handlers due to their fixed this
(es6this).
This property is not advised to change on run-time since it’s usually unpredictable when it will take effect. For example, Sqimitive\jQuery.attach() only binds events when nesting el into a new parent node:
sqim.attach()
sqim.elEvents['click'] = function () { alert('foo') }
sqim.attach() // will do nothing and 'click' will not be bound
sqim.el.remove()
sqim.attach() // now events are bound
See also the attachPath
_opt.
var MyView = Sqimitive.jQuery.extend({
el: {tag: 'form'},
elEvents: {
// Attach listener to this object's el:
submit: function (e) {
return false
// as with regular jQuery event handlers, returning false
// implies e.stopPropagation() and e.preventDefault()
},
// React on change originating from an element with specific name
// attribute:
'change [name="login"]': function () {
this.$('[name="password"]').val('')
},
// Call render() whenever value of an element with the name
// attribute changes:
'change [name]': 'render',
// Masked callback - only gives first argument to _linkClicked():
'click a': '_linkClicked.',
// Similar but the '.zyx' namespace creates a second handler,
// avoiding key collision with 'click a':
'click.zyx a': 'track',
},
})
var MyView2 = MyView.extend({
elEvents: {
// Overrides the '_linkClicked.' handler but keeps 'track'.
'click a': ...,
},
})
Defined in: jquery.js, line 277
Modifiers: static
Determines if obj
should be wrapped in $
for storing as el.
Returns true
if obj
is a native DOM Element
, Document
or
Window
. Returns false
if other, including is$()
.
Sqimitive.jQuery.canWrap(document.head) //=> true
Sqimitive.jQuery.canWrap(null) //=> false
Sqimitive.jQuery.is$($('<p>')) //=> true
Sqimitive.jQuery.canWrap($('<p>')) //=> false
_.isElement(window) //=> false
Sqimitive.jQuery.canWrap(window) //=> true
Sqimitive.jQuery.canWrap(document) //=> true
Defined in: jquery.js, lines 161-163 (3 lines) • Show code
canWrap: function (obj) {
return obj && (_.isElement(obj) || obj.nodeType === 9 || obj.window === obj)
},
Modifiers: static
Determines if obj
is a $
node (jq:jQuery or Zepto).
Sqimitive.jQuery.is$(document.rootElement) //=> false
Sqimitive.jQuery.is$($('html')) //=> true
Sqimitive.jQuery.is$($('<p>')) //=> true
Sqimitive.jQuery.is$($()) //=> true
Sqimitive.jQuery.is$(null) //=> false
Defined in: jquery.js, lines 143-145 (3 lines) • Show code
is$: function (obj) {
return obj instanceof $ || ($.zepto && $.zepto.isZ(obj))
},
Finds node(s) within own el.
Types | Notes |
---|---|
object | A jq:jQuery node. |
Possible path
’s:
Name | Types | Notes |
---|---|---|
object | that is is$() to return the path itself | Returned collection may be empty or its members may be outside of
this.el |
a DOM node (canWrap()) to wrap and return $(path)
| ||
string | empty or just . to return own el | If this .el is unset then always returns a jQuery node with zero
length |
selector to return this.el.find(path) – see jq:find()
|
this.$() //=> $(this.el) - but better use this.el
this.$('') //=> $(this.el)
this.$('.') //=> $(this.el)
this.$('a[href]') //=> $([A, A, ...])
this.$(document.body) //=> $('body')
this.$($('body')) // same
this.$('body') // empty collection unless this.el is <html>
this.el = null
this.$('') //=> $()
this.$('body') //=> $()
this.$(document.body) //=> $('body')
Defined in: jquery.js, lines 478-486 (9 lines) • Show code
$: function (path) {
if (this.constructor.is$(path) || this.constructor.canWrap(path)) {
return $(path)
} else if (this.el) {
return (path == '' || path == '.') ? this.el : this.el.find(path)
} else {
return $()
}
},
Appends el to a DOM node and binds elEvents if changed parents.
Name | Types | Notes |
---|---|---|
parent | string selector | |
object DOM or jQuery node | ||
no argument use the attachPath _opt | ||
null only bind events |
First, unless parent
is null
, attach() resolves parent
with
_parent’s $()
or global $()
(if no _parent) and, if the found
parent is a node and el’s current direct parent is different, calls
jq:appendTo() on own el and attach() on all children of self to
let them rebind their DOM listeners (but see _invokeAttach). Doesn’t
un-attach el if no parent was found. Doesn’t call render().
Second, attach() clears all existing el event listeners and binds
those defined in elEvents under the .sqim-
+ _cid jQuery
namespace (ignoring .ns
possibly present in elEvents keys – that
one is to avoid key collisions during inheritance, not for jQuery).
This happens even if parent didn’t change (above).
If el is null
then attach() does nothing.
sqim.attach('#nav') //= sqim.el.appendTo('#nav')
sqim.attach('<div>') //= appends to a new <div> node
sqim.attach(null) // re-binds elEvents only
sqim.attach('#unk') // the same
sqim.attach() // uses sqim._opt.attachPath, if set
sqim.attach(sqim.get('attachPath')) // the same
Note: if _parent is set then attach() uses its $()
. Hence even
if parent
is a globally-reachable selector (like html,head,body
)
it will never match if _parent’s el is unset or if it’s not a
parent of that node. For example, el must be $('html')
in order
to match head
:
var parent = new Sqimitive.jQuery({el: 'p'})
var child = parent.nest(new Sqimitive.jQuery).attach('body')
//=> child.el.parent() is []
Work around this by setting attachPath
or el to a DOM or $
node
or by giving one to el
after construction:
var MyView = Sqimitive.jQuery.extend({
el: window,
el: document.rootElement, // for <html>
el: document.head, // for <head>
el: document.body, // for <body>
})
// Or, on run-time by class' user:
new Sqimitive.jQuery({attachPath: document.rootElement})
new Sqimitive.jQuery({el: window}) // binds elEvents only
sqim.attach(document) // binds elEvents only
Warning: document.body
is not available if the current script is
executing from <head>
.
from baseAttach
Types | Notes |
---|---|
object | this |
Here’s a typical Sqimitive object lifecycle:
new
: new Class({opt...})
Complete re-rendering on change is simple and adequate for many simple
sqimitives but if it’s heavy, it’s customary to perform a partial update
using method(s) named update()
. There are no such methods by default
but see vw for an example.
var Label = Sqimitive.jQuery.extend({
_opt: {caption: 'untitled'},
events: {
render: function () {
this.el.text(this.get('caption'))
},
change_caption: 'render',
},
})
// Lifecycle:
;(new Label) // 1) construct
.attach('body') // 2) attach
.render() // 3) render
.set('caption', 'render again!') // 4) update
Defined in: jquery.js, lines 402-424 (23 lines) • Show code
attach: function (parent) {
arguments.length || (parent = this.get('attachPath'))
if (this.el) {
parent = parent && (this._parent ? this._parent.$(parent) : $(parent)) || []
if (_.isElement(parent[0]) && parent[0] !== this.el[0].parentNode) {
this.el.appendTo(parent)
// Notifying children of the "mount" node change.
this._invokeAttach && this.invoke('attach')
}
var namespace = '.sqim-' + this._cid
this.el.off(namespace)
_.forEach(this.elEvents, function (func, key) {
func = Sqimitive.Core.expandFunc(func, this)
key = key.match(/^\s*([^\s.]+)(\.\S*)?(\s+(.*))?$/)
key[1] += namespace
key[4] ? this.el.on(key[1], key[4], func) : this.el.on(key[1], func)
}, this)
}
},
Removes own el from DOM and unnest()-s this
from _parent.
If el is set, remove() calls either jq:remove() to drop it from DOM (if _removeEl is set) or jq:off() to unbind all own events. Then the inherited Base.remove() calls unnest() to remove this sqimitive from its _parent (if any).
remove() doesn’t recursively remove() all nested _children as
it might be undesired and slow (in DOM removing the parent node
automatically unbinds events of all children). If children do need to
perform some clean-up actions when their parent is removed – call
this.sink('remove')
(sink() is recursive) or let them subscribe
to _parent’s remove
when owned.
from baseRemove
Types | Notes |
---|---|
object | this |
rmvsunnUse unnest() when an object is temporary elided from the hierarchy (e.g. because it’s changing parents). Use remove() when it’s completely destroyed and its “view” (DOM node, etc.) is no longer needed. By convention, remove() is also used on el-less objects (where it’s identical to unnest() in effect) to convey the intention of destroying them.
var child = new Sqimitive.Base({el: '<p>Some text.</p>'})
var parent = new Sqimitive.Base({el: '<article>'})
parent.nest(child).attach(parent.el)
// now we have <article><p>Some text.</p></article>
child.unnest()
// we still have <article><p>Some text.</p></article> even though
// child is no more listed under parent._children
// But if we would have done this:
child.remove()
// we would have <article></article> with the child removed from
// both the parent's _children list and from its the parent's el
Defined in: jquery.js, line 426