ded / bonzo Goto Github PK
View Code? Open in Web Editor NEWlibrary agnostic, extensible DOM utility
License: Other
library agnostic, extensible DOM utility
License: Other
If it did, it would save a hell of a lot of bonzo.create()
s.
Anyway, it came up in IRC, and I was wondering if anyone else might be able to provide insight. If there's no good reason not to, then I'd like to propose that normalization get added...
Cheers!
Maybe I'm just not getting it, but it's thrown me for a loop on several occasions that to obtain a native DOMElement from bonzo.create()
one needs to take its [0]
.
It's extremely counterintuitive to me that its return-value is sort of neither here nor there -- not quite as sexy as a bonzo object, and yet it's also not as straightforward as a native DOMElement
, either: just a clumsy worst-of-both-worlds situation somewhere in between.
I always instinctively assume that if I just do bonzo.create('<alksdj>')
, then I'll get a native element because if I want to get a bonzo object, I still need to wrap it in bonzo()
anyway, like so: bonzo(bonzo.create('<foo>'))
.
It's doubly bad, because after I finally figure out that #94 is what's been breaking my code, I move on from the create()
statement, naively assuming that the remaining bugs must lie elsewhere.
I should note that I'm pretty new to ender, so it could very possibly be just me. Another possibility is that this is super bikesheddy, and should accordingly be totally ignored by any serious developers reading it as a silly n00b-rant -- take it with a grain of salt.
Cheers!
on the last line of bonzo.js:
}, this); // the only line we care about using a semi-colon. placed here for concatenation tools
currently, this breaks browserify (it assumes a newline on the end of the file)
This could be resolved by adding a newline to the file, or by turning the comment into a /**/ one.
Demonstration at http://jsfiddle.net/2NA6E/3/ โ when any offsetParent in the chain checked by offset() is positioned, its border-widths wind up subtracted from the final offset value that's calculated and returned.
Attempting to write innerHTML or appendChild to an unknown element in old versions of IE results in an Unknown runtime error
from those browsers (even if the element is declared using document.createElement('time')
previously.)
e.g.
var $t = $('time')
$t.html("10 minutes ago")
Will trigger the error in IE.
Might be worth looking at @jdbartlett's innerShiv, although I think that may only handle the creation of unknown/HTML5 elements within elements that are already functional nodes, rather than the enabling of DOM functionality on those unknown elements.
IE9 and IE10 are supporting the opacity css property. It would be better to use it instead of filters.
You might use -ms-filter if the browser is IE8, because the original filter property might cause issues.
Hi,
Bonzo (and Reqwest + Qwery) all produce an empty named AMD module when used with r.js
They all produces this after compilation, alongside the original module :-
define("bonzo",[], function(){});
Test case, https://github.com/guardian/requirejs-optimiser-bug
requirejs (client-side) conveniently ignores this, but curl and almond throw exceptions due to duplicate module names.
So, I think r.js is misinterpreting this line for some reason,
else if (typeof context['define'] == 'function' && context['define']['amd']) define(name, definition)
Various other modules (Eg, bean etc.) don't have this problem.
I'm using the latest r.js package,
r.js -v
r.js: 2.0.6, RequireJS: 2.0.6
Thanks,
M
If the browser does not support classList toggleClass does not have the same behaviour.
If the toggled class already exists on an element toggleClass will add that same class to the className string, which means the class can never be removed.
This is caused by the internal addClass function not checking for the new class existing in the className string before appending.
I suppose the fix would be something like:
addClass = function (el, c) { if (!hasClass(el,c) { el.className = trim(el.className + ' ' + c); } }
That would unfortunately make the addClass API call hasClass twice.
However, given that add/removeClass API functions now have the same functionality as their classList equivalents the hasClass checks are now unnecessary and can be removed.
EDIT
Is there any specific reason to why the function
offset()
is called like that, and notposition()
, like in jQuery?Since
offsetLeft
, etc.. all measure the offset to their next offsetParent, it seams kind of strange to have offset() return the position in the browser window...
Ok.. I'm sorry, I confused the jQuery functions. It's just that position() is missing from bonzos toolkit.
Trail starts here: https://twitter.com/getify/status/248137610113986560
I gather that while we can create script elements they don't actually work.
/cc @getify
In IE7 and 8, if I run something like this:
var itemsWidth = 0;
$('li').each(function (el) {
var width = $(this).width();
itemsWidth += width;
});
IE will return a value of 'auto' for the width unless it is explicitly set in CSS. This is a bit of a problem when you are running over items that you don't know the content of and need to set the parent object's width dynamically.
These public functions that return something other than the container object all return vanilla arrays:
bonzo.next()
bonzo.previous()
bonzo.detach()
bonzo.map()
bonzo.related()
And these public functions that all return something other than the container object all return a Bonzo()
style array:
bonzo.first()
bonzo.last()
So, for example, if you call bonzo([el1, el2]).next()
you get [el3, el4]
where they are the nextSibling
elements for the original pair. But if you call bonzo([el1, el2]).first()
, you get a bonzo([el1])
.
For the other functions, they mostly operate through the internal each()
which simply returns this
so you get a bonzo()
object like first()
and last()
. For the functions in the first category above, they operate through bonzo.map()
which returns a fresh array, []
.
This doesn't matter so much for Ender because the bridge takes care of it but there are consistency issues for using Bonzo alone, chaining function calls is interrupted: bonzo([el1, el2]).show().next().hide()
doesn't work because you're operating on a non-Bonzo-wrapped object after the next()
call.
I'd love to fix this and submit a PR but perhaps it's intentional? My proposal would be to always return a Bonzo-wrapped array so you can chain your calls and everything is consistent. The only one that makes sense not to wrap is perhaps map()
which could return arrays of pretty much anything depending on your callback function, but this would need to be documented in the README.
function dataValue(d) {
try {
return d === 'true' ? true : d === 'false' ? false : d === 'null' ? null : !isNaN(d) ? parseFloat(d) : d;
} catch(e) {}
return undefined
}
is returning NaN
for a bunch of d
values where it should probably return something else, undefined
or null
probably. Most importantly these values give NaN
: ''
, null
(probably the culprit).
needs test cases.
yes, blame me.
define(['bonzo'], function(bonzo) {
console.log(bonzo)
})
// -> undefined
If I'm wrong, please correct;
If looking for document height, then seems something wrong width this line (cos it gives same result with width
).
https://github.com/ded/bonzo/blob/master/bonzo.js#L858
Test: var dims = bonzo(document).dim(); console.log(dims.width, "x", dims.height)
Output: 1263x1263
Math.max(el.body.scrollHeight, el.body.offsetHeight, de.scrollWidth, de.offsetWidth, de.clientHeight)
And, I think it shold be like;
Math.max(el.body.scrollHeight, el.body.offsetHeight, de.scrollHeight, de.offsetHeight, de.clientHeight)
IMO, bonzo should the setting of an elements value if the values type is wither a string or a number.
Just an idea, how do you feel about a create function that accepts a properties?
Instead of MooTools' Element syntax, there could be something like this:
var elem = $.create('canvas', {
width: 400,
height: 300
});
OR
var template = $("#myCanvas");
var elem = $.create(template, {
width: 400,
height: 300
});
I think that passing in this style of syntax really makes sense, and is more javascript-y than having to construct an HTML string.
My use case is canvas; reason being, canvas' height/width can't be changed on the fly, so they have to be recreated every time the width and height change (like on a mobile device when the orientation changes).
I like this syntax a lot better than the existing jQuery-style syntax. What do you think? Is there already a way to do this that I didn't notice?
Hi,
I'd like to ask for support of a method that can replace a node with another node.
Currently I created this simple function:
$.ender({
replaceWith: function(text) {
return this.each(function (el) {
var newEl = $.create(text);
el.parentNode.replaceChild(newEl[0], el);
});
}
}, $);
but this method doesn't work for all cases and on all browsers.
For example
$.domReady(function() {
$('#table').bind('click', function(event) {
var newHtml =
"<table border='1'>"+
"<thead>"+
"<tr>"+
"<th>some head data</th>"+
"</tr>"+
"</thead>"+
"<tbody>"+
"<tr>"+
"<td>some data</td>"+
"</tr>"+
"</tbody>"+
"<tfoot>"+
"<tr>"+
"<td>some foot data</td>"+
"</tr>"+
"</tfoot>"+
"</table>"
;
$(this).replaceWith(newHtml);
});
$('#title').bind('click', function(event) {
$('title').replaceWith("<title>new title</title>");
});
$('#script').bind('click', function(event) {
var script =
"<scr"+"ipt>console.log('inline');</scr"+"ipt>"+
"<scr"+"ipt src='outerHtml-script.js'></scr"+"ipt>"
;
$(this).replaceWith(script);
});
});
Do you think such kind of functionality can be added to Bonzo ?
I need it to replace a custom solution which you can see at http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/ajax/wicket-ajax.js?view=markup between lines 178 and 391. We'd like to replace this code with something provided by a JavaScript library specialized in DOM manipulation, like Bonzo.
Hi! How do I disable/enable elements with bonzo? TIA
Bonzo defines itself to RequireJS as an anonymous module. The RequireJS library (require.js), when requiring the modules from separated files, takes the module name from the file name and it works perfectly. However, the compiler is dumb, and it cannot detect bonzo's module name from the filename because the define() call isn't in the beginning of the file.
This change makes bonzo pass the module name to RequireJS manually, fixing the problem:
diff --git a/src/bonzo.js b/src/bonzo.js
index 99e66d5..b5dc08a 100644
--- a/src/bonzo.js
+++ b/src/bonzo.js
@@ -1,5 +1,5 @@
!function (name, definition){
- if (typeof define == 'function') define(definition)
+ if (typeof define == 'function') define(name, definition)
else if (typeof module != 'undefined') module.exports = definition()
else this[name] = definition()
}('bonzo', function() {
show()
uses display=''
with possible override type
toggle()
uses display='block'
with no possible override
they should determine most appropriate display value for the particular element either from existing style information or perhaps by creating virgin elements and testing them and caching the values for each element type.
hide()
should probably save the old display value so that can be restored by show()
.
We should do this so that data doesn't jsut build up for no reason...
Currently bower checks out bonzo version '1.0.0' (built 2 years ago), which won't include setQueryEngine
, for example. Though the current version seems to be '1.3.0', bower will only recognize it if there is a Git tag.
$('body').parents();
> TypeError: Cannot read property 'nodeName' of undefined
For the moment I'm solving this by doing $('body').parents('*')
.
I was going to create a unit test to demonstrate this, but I need #70 first. Not sure what the best approach is for doing pull requests w/ dependencies.
After doing a simple ender build bonzo
and creating a page that includes ender.js
, in Chrome I am given this error:
Uncaught TypeError: Object #<Object> has no method 'setQueryEngine'
Seems to be that setQueryEngine is undefined on the object returned from require("bonzo") - even before it's first called.
Uncaught TypeError: Object [object HTMLParagraphElement],[object HTMLParagraphElement],[object HTMLParagraphElement],[object HTMLParagraphElement],[object HTMLParagraphElement],[object HTMLParagraphElement],[object HTMLParagraphElement] has no method 'color'
Discussed this with @rvagg in IRC briefly. Here's the alias I would propose:
bonzo.new = function(tagname) {
return bonzo.create('<'+ tagname +'>');
};
It could obviously be implemented more performantly as a direct interface to the DOM, but I think it would be a more intuitive API. The current name create()
evokes the native DOM's document.create()
, which accepts a tag name, not a tag. So intuitively I always want to write bonzo.create('div')
, and not bonzo.create('<div>')
. That was perhaps the most recurring hitch in my adjustment to the API, FWIW.
Hi, Today I found a strange behavior with checkboxes...
1- Preparing some checkboxes...
<input type="checkbox" checked="checked">
<input type="checkbox" checked="checked">
<input type="checkbox" checked="checked">
<input type="checkbox" checked="checked">
<input type="checkbox" checked="checked">
2- Test this code for uncheck all and result is OK
$("input[type='checkbox']").removeAttr('checked')
3- Test this code for check all and result is OK
$("input[type='checkbox']").attr('checked', 'checked')
4- Now, change some of the checkboxes manually, and repeat step 2 and 3... only change I have not touched manually
I tested this issue on chrome and firefox with same results.
The test with jquery is ok.
Is a possible error of qwery, not finding the elements that change...
With .hide
being the style display: none;
Since it gets the initial collection using $(selector) and then filters it, it fails to find any elements that aren't attached to the current document.
Hello,
When using the offset method with zeros for the coordinates, the method returns the offset position object instead of actually positioning the element.
I.e.
.offset(0, 0) returns { left: 123, right: 123, width: 123, height: 123 }
Cf. line 387
if (x || y) {
should be something like
if (x || y || x === 0) {
Cheers,
Pierre
bonzo.map() binds 'this' inside the callback to the current bonzo instance and passes the iterated element as the first argument to the callback. This is different from jQuery, which binds 'this' to the current element and passes the index as the first callback argument.
Bonzo also returns an array whereas jQuery returns a new jQuery object.
Are these differences intended?
In general, is bonzo intended to behave like-for-like with jQuery where it defines functions with the same names?
Thanks
For example:
#example {
padding:10px;
font-size:14px;
}
bonzo(document.getElementById('example')).css('padding'); //Returns a blank string
bonzo(document.getElementById('example')).css('font-size'); //Returns 14px
I did some testing outside of bonzo and I'm pretty sure this is because the browsers are converting padding:10px
to padding-top:10px
, padding-bottom:10x
, etc
I just threw this in hoping it'd work because i didn't want to write out the utility function myself in my library, but once i write it ill send you a pull request. I believe for margin (didn't test), padding, and other short-hand styles you'll need to see if .css('X') returns a blank string, if so, does padding-top, if padding-top !== blank string then return the value of padding-top back.
If my css has display: none, and I call .show() on the element, the element doesn't show up. I dove deeper and noticed that the .show() function is setting the display value to "" rather than block.
if a div has a class .hide
which sets display:none
then bonzo's show()
will simply set el.style.display = ""
this will not override the class's value.
instead i have to call show('block')
to get it to work. jquery has an overly complicated method allowing it to properly set the default display to elements (since sometimes showing means making the display inline, inline-block, table-row, etc etc....)
css3 has an initial
value that works on all attributes (https://developer.mozilla.org/en/CSS/initial) which would be perfect in this scenario, but the browser support is limited right now.
you could take the 80% approach and set the display to block
and get most of the way there.
i'm just manually setting mine as it isn't a big deal, but it is a quick 'gotcha' for those new to bonzo coming from jquery
Setting the opacity of an element to 0 doesn't work.
I think it is due to the fact that 'px' is appended to 0.
If I have used setQueryEngine to add qwery to bonzo, the reference to qwery is kept in an inner variable that cannot be accessed from outside the bonzo object. I'd like to be able to chain a call to that qwery, like so:
$('ul').addClass('outer').find('li').addClass('inner');
Is this a useful feature generally? If so, I will be happy to provide a pull request.
Do you guys have any plans to allow the children()
and siblings()
methods allow a selector
argument for filtering? Also, a filter()
method would be nice as well.
I found that in IE 8, $("form select").html("op_1")
would change 's innerHTML to be op_1. Rather peculiar.
Doing: $("<p>").append("<span>Here</span> Gone")
Results in only <span>Here</span>
being appended.
The above seems unintuitive to me. I am wondering if this could be considered a bug or if it's really intended to happen? If it's intended I was wondering if there was a rational reason this happens because it seems that we have to literally go out of our way when building with $("")
it also means that if we want to continue to use $("")
to build we must pull the $().html()
and join it when trying to add multiple (seperately built) pieces to the element and then on the last part of the chain just use $("").html
like below:
twt_paragraph.append(twt_anchor);
twt_ele.html(twt_paragraph.html(twt_paragraph.html()+link_users(tweets[i].text)));
According to Ender and the DOM I have "0.4.3-dev".
testet with [email protected] build
DOM4 includes mutation methods: append()
, prepend()
, before()
, after()
, replace()
, and remove()
, potentially taking a variety of argument types (nodes, strings). Would be great to (1) benchmark and (2) leverage these methods in Bonzo (when they are available!).
remove()
is already in WebKit with the rest to come.
/ht @paulirish @ https://plus.google.com/u/0/113127438179392830442/posts/KLfpJKLDEsv
Can't remember, but jQuery might do this. In any case, it would make for more predictable behavior. I'm just not badass enough to be able to implement it.
appendTo
, prependTo
, insertBefore
, insertAfter
; all the methods calling insert
clone the node they move. This caused weird behaviour in my test project, since references suddenly pointed to document-less fragments and not the code I just appended.
Just wanted to verify that this is intended behaviour and why? Maybe I learn something new about what this fixes or why it is good behaviour?
For better jQuery compatibility it would be good to have jQuery's DOM Insertion, Around methods: wrap, wrapAll, wrapInner and unwrap.
bonzo implementation of each() returns this
, but underscore is now returning undefined
instead (which is coherent with the latest state of ECMAScript 5, see http://ie.microsoft.com/testdrive/HTML5/ECMAScript5Array/Default.html ). This is breaking some implementations, notably empty() and html().
It has been reiterated that underscore is not intending to change their implementation, see
jashkenas/underscore#73
jashkenas/underscore#74
jashkenas/underscore#142
I suppose that bonzo should also abide by this contract or push to change the standard (I agree that returning undefined
is useless, but that is hardly the point here)
Example:
$('.slide', this.mainStage).last().animate({....});
Brings the error that animate() is not a method. Workaround right now is to wrap
Would be nice if last returned an object that is directly chainable with other methods like .animate()
It would be nice to have possibility to use selectors inside the next and previous functions, for example to find next visible element or next element with the same class.
what do you think?
Hi!
$('input')[0].attr('value', 'foo')
does nothing (at least in Chrome 9.0.597.94 on Linux 32-bit, debian 6.0). Instead, $('input')[0].value = 'foo'
does work.
What is the way to robustly get/set value
property of an elemnt in bonzo?
TIA,
--Vladimir
Currently the setQueryEngine does not return any value, so if I want to add a query engine and then call noConflict, I have to write two lines of code. If setQueryEngine returned a reference to bonzo I could write a single chained line like so:
var q = window.qwery.noConflict(),
b = window.bonzo.setQueryEngine(q).noConflict(); // chain!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.