Archive for the ‘Javascript’ Category

No Comments

Sorting with Flexbox

Wednesday, August 13th, 2014

The Flexible Box Layout Module is a very powerful tool to style your webpages. It offers simple solutions for things like `the Holy Grail`

Here we do a dirty sorting trick:

Just push the buttons or table header to sort the stuff.

How does it work

Sort the elements on text and write the order attribute for CSS.

<li style="order: 7;">scstqehfr</li>

Then set the elements to display flex on the ol element:

.sorted{
display:flex;
flex-flow:column;
flex-direction:column;
}

Be aware:

Sorting this way is kind of superficial, it’s only ordered through CSS: It will show the elements in different order, but in the DOM there is no change at all. So traversing or accessing elements can be surprising, it will go in original/DOM order.

Sorting an table through Flexbox ruins the layout, because it resets the display property from `table-*` to `flex-*`. An additional trick to write the width explicitly is needed to maintain layout.

No Comments

How to get a selection of text with JavaScript

Wednesday, October 31st, 2012

JavaScript is a language full of surprises, sometimes it’s dead simple, sometimes it’s complex or counterintuitive. In its early years it was considered as a toy for making wacky DHTML effects on pages, but it actually has elegant and powerful capabilities. Actually most problems rise out of cross-browser issues, and proprietary implementations for the DOM extensions.

To get a selection of text – user selected text by the user that can be copied to the clipboard – can be accessed by JavaScript as easy as this:

document.getSelection()
//document.getSelection().toString()

Wow, but it wouldn’t be this world if there aren’t any cross-browser issues.

The downside: It works for normal text on pages, but it doesn’t  work for input or textarea elements in Firefox or Opera. It does work in Chromium in all cases.

For Firefox or Opera you need this, slightly more complex, code:

// get active Element

var el = document.activeElement, start = el.selectionStart, end = el.selectionEnd;
var selection = el.value.substring(start, end);

Wouldn’t it be nice if Firefox and Opera make document.getSelection()  work like Chromium?

Yes, I guess, but there is another quirk. In Opera you can have multiple selections, you can select text in a texarea field, and leave that selected while you copy text somewhere else. I’m not sure why that is, sometimes confusing sometimes it’s convenient.

No Comments

Spinners and sliders with just native javascript

Thursday, April 5th, 2012

In an earlier post we waved goodbye to jQuery UI for animations. CSS transform and transitions are more powerful, easier to maintain, hardware accelerated, and last but not least less code.

And you could save bandwidth by not loading jQuery UI.

And now I have rewritten the former example to drop jQuery, and believe it or not, it’s even less inline Javascript code. Sure the former example wasn’t really clever programmed – now we use event delegations – but it’s quiet astonishing that using native JS requires less code then the former jQuery example. And of course one library less to load.

Why can we drop jQuery in a lot of cases?

Because CSS animations aren’t working in old browsers anyway, so it doesn’t matter that don’t understand the latest HTML5/ECMA Script 5 / Javascript additions. That’s what graceful degradation means. No eye-candy for older browsers.

Important HTML5/ECMA Script 5 / Javascript additions:

  • classList api: easy toggling, adding and removing of classes.
  • document.querySelectorAll, the native selector API,  get you’re DOM elements like the way you do with CSS
  • new powerful array functions, like forEach etc.
  • even Microsoft products (Explorer 9) now support Javascript specs: like addEventListener, XMLHttpRequest,  javascript objects instead of ActiveX objects etc.
  • innerHTML, outerHTML
  • DOM traversal

Above list is not complete, but in most cases jQuery was used for things like, binding events, toggling classes, selecting elements, add elements, and ajaxify sites.

Here is the new example

And the used Javascript code:


(function(){
var spinner = document.getElementById("spinner"),i=null
spinner.addEventListener('click', function(event){
// event.preventDefault()
// event.stopPropagation()
// which element is the target
i = Array.prototype.indexOf.call(spinner.children, event.target);
// if(window.console) console.log(i,event)
switch(i){
case 1:
// clicked left, pop -> unshift
spinner.insertBefore(spinner.lastElementChild, spinner.firstElementChild)
break;
case 3:
// clicked right shift -> push
spinner.appendChild(spinner.firstElementChild)
break;
default:
}
// Opera bug workaround
spinner.classList.toggle('operabug')
}, false);
})()

Caveats

The Opera bug with DOM mutations and CSS transform/transitions isn’t resolved yet unfortunately. Somehow the DOM mutations don’t seem to trigger a reflow.

UPDATE: there is an easy fix for the Opera Bug, trigger a reflow by setting a bogus class on any element:

// Opera bug workaround
spinner.classList.toggle('operabug')

No Comments

How to manipulate styles with javascript

Thursday, March 15th, 2012

In the DOM the document has a styleSheets property which is a StyleSheetList object, which is a collection of CSSStyleSheet objects which has a cssRules property which is a CSSRuleList object which is a collection of CSSStyleRule objects.

alert(document.styleSheets[0].cssRules[0].cssText)

And the  CSSStyleRule has a cssText property which gives a CSS rule declaration like

body{background-color:white;}
The StyleSheetList and the CSSRuleList are array like objects, but like domNodeList you can’t call foreach methods on it but they are enumable with a loop. Each style tag or link tag to an external  stylesheet is created as a seperate StyleSheetList object. That does make sense, but sometimes one big array of rules can come in hand to. This is the code to achieve that. We use some tricks like calling the splice method to  list to create arrays.
var rules = Array(),superCSSSheet='';

Array.prototype.slice.call(document.styleSheets).forEach(function(sheet){

 rules = rules.concat(Array.prototype.slice.call(sheet.cssRules))

 })

rules.forEach(function(rule){
superCSSSheet += rule.cssText+"\n"
})
alert(superCSSSheet)

Which clearly shows WordPress isn’t very efficient with CSS code: to be more specific most themes and plugin aren’t 🙂

Another funny thing came to attention is that CSS color values are read out differently then set.

No Comments

CSS vendor prefix issues

Thursday, February 16th, 2012

Vendor prefixes are the verbose code you see in new `HTML5` sites, in which browser vendors test their new CSS3 rules, when specs are in proposal time or under development.

Something like:


-o-transition: opacity 1s ease-in 1s; //opera
-moz-transition: opacity 1s ease-in 1s; /firefox
-ms-transition: opacity 1s ease-in 1s; // internet explorer
-webkit-transition: opacity 1s ease-in 1s; // safari , chrome
-khtml-transition: opacity 1s ease-in 1s; // konquerer , linux
transition: opacity 1s ease-in 1s; // all when it's official spec

The problem is that most developers seem to do just this:

-webkit-transition: opacity 1s ease-in 1s; // safari , chrome

So they only support webkit browsers and that is plain dumb. At least you should always add the rule without any prefix. That means eventually it will work in every browser that supports it.
Typing all the rules is a pain in the ass, so most developers only do webkit, probably also because Apple invented quite a lot for transitions etc. At that time it was not supported by any other browser, so why on earth should you add code that has no meaning. Well because you care about the future and care about different minded people.

Two helpful solutions

First there are macro’s for IDE’s to type one rule and auto generate the other ones. Here is a CSS vendor prefix macro for Netbeans. Not much of a hassle.

Secondly you can call userJS to the rescue, userJS is like userCSS a rather underestimated part of the internet, but yet a very valuable one. It let you overrule CSS rules or run own JS in websites.

For Opera add this as a userJS:

opera.addEventListener('BeforeCSS', function(userJSEvent){
userJSEvent.cssText = userJSEvent.cssText
.replace(/-(moz|ms|webkit|o)-(border|text-overflow)/g,'$2')
.replace(/-(moz|ms|webkit)-(gradient|transform|transition)/g,'-o-$2');
}, false);

Source here

It will automatically rewrite all -webkit- rules to -o-  rules in Opera, so all the webkit  demo’s will start to work. (if Opera supports them)

Caveats

  • Code (css specs) can change during development.
  • Implementations differ between vendors.

Of course these are workarounds, I still think developers should add all vendor prefixes to their code. It can be automated in an IDE like with mentioned macro for Netbeans or in deployment.

1 Comment

Canvas Rendering: Skewing Images by Javascript

Saturday, November 8th, 2008

The new HTML5 CANVAS element gives the developer pixel-poking magic. Poke and peek are functions from the good old days that offered the only geeky way to set and read-out individual bytes in the (graphic) memory.

Sure things are better nowadays. To understand how canvas works, imagine an IMG element, of which every pixel can be set individually or loaded from a IMG source.

Opera screenshot canvas element

Opera screenshot canvas element

This means you can filter images, copy them, translate, rotate, scale, in short: a lot. It can also add drop-shadow, although at the moment this is only fully supported by Safari and partially by Opera. Probably Firefox will add support in the upcoming 3.1.

sec



Rendering is best in Opera and Firefox. Safari and Chrome look awful. Webkits’ canvas seems designed to work only with integers while Opera and Firefox translates floats into some anti-alias rendering. Better but probably slower. Opera’s rendering is quite slow.

Update 25-02-2011

Rendering time screen:

Chrome 9 : 50 msec
Opera 11.01:  667 msec
Firefox 3.613: 2829 msec

Opera and Firefox look fine, Chrome’s rendering is jagged.