Git Product home page Git Product logo

youmightnotneedjquery's Introduction

You Might Not Need jQuery

Build Workflow

A resource for doing things au naturel.

Contributing

To add a new section, just create a folder for it, and add jquery.js, and ie8.js, ie9.js, ie10.js, ie11.js, and modern.js (for Chrome/Safari/Firefox) as needed. For example, if you have ie8.js and ie9.js, the ie9 version will be shown to people looking for a solution that works in ie9, ie10, ie11, or modern JS.

Building

Building YMNNJQ requires Node.js

  1. In the project directory, run npm install
  2. To build the project and watch for changes, run npm run dev.
  3. To build the project without watching for changes, use npm run build.

youmightnotneedjquery's People

Contributors

abbondanzo avatar adamschwartz avatar banderson avatar burtchen avatar cozmbatman avatar damieng avatar davidbonting avatar eipark avatar extempl avatar fabricionaweb avatar fhemberger avatar frandias avatar headbandno2 avatar iamstarkov avatar jarikmarwede avatar kylebakerio avatar mscuthbert avatar nickmccurdy avatar odahcam avatar pborreli avatar peterwhittaker avatar philippwiesemann avatar ramyareye avatar richienb avatar rkrupinski avatar rwaldron avatar simeydotme avatar simonneutert avatar yukulele avatar zackbloom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

youmightnotneedjquery's Issues

CustomEvents in IE9 don't work as written

I believe it should be this instead:

if (typeof CustomEvent === 'function') {
  var event = new CustomEvent('my-event', {detail: {some: 'data'}});
} else {
  var event = document.createEvent('CustomEvent');
  event.initCustomEvent('my-event', true, true, {some: 'data'});
}

el.dispatchEvent(event);

In the current version, the if statement passes (because window.CustomEvent is an object) but the new statement after that fails (because IE9 doesn't really support custom events).

A mention of jQuery's support for custom builds.

I think a note on jQuery's support of custom builds for 1.9+ and 2+ would align with the youmightnotneedjquery sentiment:

Maybe you can include a few lines of utility code, and forgo the requirement. If you're only targeting more modern browsers, you might not need anything more than what the browser ships with.

For more info on custom builds check out jQuery's readme.

The builds even support removing Sizzle and using querySelectorAll

As a special case, you may also replace Sizzle by using a special flag grunt custom:-sizzle.

  • sizzle: The Sizzle selector engine. When this module is excluded, it is replaced by a rudimentary selector engine based on the browser's querySelectorAll method that does not support jQuery selector extensions or enhanced semantics. See the selector-native.js file for details.

Note: Excluding Sizzle will also exclude all jQuery selector extensions (such as effects/animatedSelector and css/hiddenVisibleSelectors).

Incorrect code order on page re: XMLHttpRequest examples

wrong:

request = new XMLHttpRequest
request.open('GET', '/my/url', true)
request.send()

request.onload = function() {
  resp = request.responseText

}

request.onerror = function() {

}

correct:

request = new XMLHttpRequest
request.open('GET', '/my/url', true)
request.onload = function() {
  resp = request.responseText

}

request.onerror = function() {

}
request.send()

A co-worker pointed this out.

trigger & dispatchEvent

updated @ 2014/02/04

trigger & dispatchEvent are different

Don't replace $.trigger & dispatchEvent simply.

FIrst, $.trigger does browser default actions if possible.

$(el).trigger("click") // do click()
$(el).trigger("focus") // do focus()

dispatchEvent does not. It simply dispatches event object.

el.dispatchEvent( new Event("click") ) // no click
el.dispatchEvent( new Event("focus") ) // no click

(new Event and document.createEvent('HTMLEvents') are the same. I'm using new Event just because it's short.)

Basically, created events by script do not trigger browser default actions.
Click event is special. new MouseEvent("click") does browser default click.
http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events

Expample

click

replaceable

$("#id").trigger("click") // click()
el.dispatchEvent( new MouseEvent("click", {bubbles: true}) ) // i'm not sure about cancelable

not replaceable

$("#id").trigger("click") // click()
el.dispatchEvent( new Event("click", {bubbles: true}) )  // no click

replaceable

$("#id").triggerHandler("click") // no click
el.dispatchEvent( new Event("click", {bubbles: false}) ) // no click

other

replaceable

$("#id").trigger("change") // no change
el.dispatchEvent( new Event("change", {bubbles: true}) ) // no change

not replaceable

$("#id").trigger("focus") // focus()
el.dispatchEvent( new Event("focus", {bubbles: true}) ) // no focus
el.dispatchEvent( new FocusEvent("focus", {bubbles: true}) ) // no focus

demo:
http://jsfiddle.net/uS636/1/


Second, $.trigger runs on all matched elements.

$("p").trigger("click") // click all <p> elements

In pure JS,

Array.prototype.forEach.call(document.querySelectorAll("p"), function(e){
  e.dispatchEvent( new MouseEvent("click", {bubbles: true}) )
})

There are many other differences.
So you can't replace $.trigger & dispatchEvent that simply.

Trigger Custom / Trigger Native

Eventlistener does not see event interface.
Eventlistener just responds to event.type.
The following two event object invoke Eventlistener's callback.

// code in Trigger Custom
event = new CustomEvent('change')
el.dispatchEvent(event)

// code in Trigger Native
event = document.createEvent('HTMLEvents')
event.initEvent('change', true, false)
el.dispatchEvent(event)

Demo:
http://jsfiddle.net/McZpC/2/

change event has no default action. There are no difference between dispatching (a)Event whose type is change and (b)CustomEvent whose type is change

But when the event type is click, there IS a difference.

// same
$("#id").trigger("change")
el.dispatchEvent( new Event("change", {bubbles: true}) )

// diff
$("#id").trigger("click")
el.dispatchEvent( new Event("change", {bubbles: true}) )

So it's not appropriate to use 'change' event as Trigger Native example.

Solution

(i remove this section. it was not correct, sorry)

Ehem. Only IE? Ehem.

So you have this beautiful website with tons of useful information and then the only web browsers that are ever mentioned are only those that have actually fallen out of favor in many parts of this planet.

Maybe there should be at least a note that Firefox and Chrome have none of those IE problems?

Custom Event in IE8

On the line 1201 you suggest to use jQuery, because IE8 does not know any custom events. That is true, but since you already suggest something else than vanilla JS solution, why not https://github.com/ondras/ie8eventtarget ? That is a polyfill for actually all the standard-based events + it does the trick for a custom event. I know you want to show that it can be done without polyfills, but since this one can't be done without any, I find this one better than actually using jQuery.

FadeIn didn't work

I ran it in a bookmarklet, and it wasn't increasing the opacity at all (Chome 31). It seemed like it might have been concatenating the value as if it were a string for some reason.

I change the line to this

el.style.opacity = Number(el.style.opacity) + (new Date - last) / 400;

and it seemed to fix it right up.

contains

http://youmightnotneedjquery.com/#contains

$.contains(document.body, document.body) // false
document.body.contains(document.body) // true

this can be pollyfilled easily, but it is confusing to use the same name, isn't it?

function contains(el, child) {
  if (el !== child) {
    return el.contains(child)
  }
    return false
}
$.contains(document, document) // false
contains(document, document) // false
document.contains(document) // true

Rename?

outerHTML jQuery example is ridiculous

This:

$('<div>').append($(el).clone()).html();

is absolutely ridiculous. Having jQuery doesn't forbid you from using native methods where appropriate.

Any sane jQuery user would do el.outerHTML rather than a barrel roll you're suggesting.

And if you start with $el rather then el, the reasonable way to do it would be:

$el.get(0).outerHTML;

or

$el[0].outerHTML;

Don't be ridiculous trying to prove your point.

Remove Class RegExp is unreliable

I don't think the remove class RegExp implementation works correctly. Currently it's this:

el.className = el.className.replace(new RegExp('(^| )' + className.split(' ').join('|') + '( |$)', 'gi'), ' ')

For example, if the element has classes 'a b ab' and you try to remove 'a b' it will also strip the 'b' from 'ab'. The joined | needs parentheses.

It also struggles with repeated classes like 'a a a'. Trying to remove 'a' will only remove some of them. I believe this is because replacement spaces can't count towards a match.

I've been experimenting and this is what I've come up with so far:

el.className = (' ' + el.className.replace(/ /g, '  ') + ' ')
    .replace(new RegExp(' (' + className.split(/ +/).join('|') + ') ', 'gi'), '')
    .replace(/ +/, ' ');

element.find() is not quite equivalent to element.querySelectorAll()

element.querySelectorAll can work well in most cases, but they are not equivalent in some cases.

// 2: Gets all divs except parent.
console.log ($(document.body).find('* > div').length)

// 3: Gets all divs including parent.
console.log ((document.body).querySelectorAll('* > div').length)

// Gets only elements matching from source/parent element, without recursion. No equivalent in pure JS.
console.log ($(document.body).find('> div').get(0).innerHTML)

http://jsfiddle.net/bezd8/

isArray badly broken

The current isArray implementation is badly broken:

isArray = Array.isArray || function(arr) {
  return arr.toString() == '[object Array]'
}

isArray(arr)

The fallback function is totally wrong. e.g.:

isArray('[object Array]') // true
isArray([1, 2, 3]) // false
isArray(null) // boom!

The 'standard' implementation for isArray uses the default toString method from the Object class, not the passed object. e.g. Something like this:

return {}.toString.call(arr) === '[object Array]';

In practice you'd usually capture the toString function in a closure rather than creating a new object for each invocation.

javascript version of .toggle();

I new to github and dont know almost everything. I cannot find .toggle() in youmighnotneedjquery.com. I have similar js to do that. I fight jQuery

el.addEventListener('click', function() {
  if(el2.offsetWidth > 0 || el2.offsetHeight > 0) {
    el2.style.display = 'none';
  } else {
    el2.style.display = '';
  }
});

on/off lose context in IE8

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener

There is a drawback to attachEvent, the value of this will be a reference to the window object instead of the element on which it was fired.

The correct way to do it is

function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler)
  } else {
    el.attachEvent('on' + eventName, function() {
      handler.apply(el, arguments);
    })
  }
}

addEventListener(el, eventName, handler)

IE version slider postion

Fix the IE version slider position to the top of the page when it hits the top. This will let users switch between versions when actually looking at the code so they can see the differences without having to scroll back and forth and remember what the previous code looked like.

Tiny Components

I am a big fan of tiny components, therefore I think big monolithic libraries, like jQuery should be phased out. It should be very easy to load only the pieces you actually need. This would be especially important for libraries.

Thank you for popularizing this point of view.

However, people shouldn't implement everything for themselves either: people should be able to (re)use code that has already been written -- and written well.

Do you think it would be a good idea to make some (of the more complex ones, if not all) of your proposed alternatives available with loadr?
An example:

They could be available like

require github://HubSpot/ajax/json

which would load

window.ajax = window.ajax || {}
ajax.json = function (url, cb) {
  request = new XMLHttpRequest
  request.open('GET', url, true)
  request.send()

  request.onload = function() {
    cb(JSON.parse(request.responseText))
  }
}

that could be used like

ajax.json('/path/to.json', handlerFn)

Because

  1. Everyone loves abstraction and memorable APIs.
  2. Programmers would still place these snippets into function bodies. Code feels cold naked. Let's do it for them, shall we?

What do you think?

P.S. Nice to see new educational JavaScript material popping up using ASI. :) Thanks for that, too.

Ajax post request wrong argument to send

Supplying send with a data object will not work, the data needs to be encoded to a string in the form of 'key=value&...' or atleast do something like JSON.stringify on the data object. Am I missing something? because trying this does not work for me and the Mozilla docs also do not subscribe this behavior for the send method: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#send()

Mentioned code:

var request = new XMLHttpRequest();
request.open('POST', '/my/url', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(data);

insertAdjacentHTML

sidebar as an index

It's better to have a sidebar (whether left or right side of the website) as an index to access subjects faster. What would you say about that?

Events - On: Cannot remove handler added by `attachEvent` (IE8+)

http://youmightnotneedjquery.com/#on

function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler);
  } else {
    el.attachEvent('on' + eventName, function(){
      handler.call(el);
    });
  }
}

addEventListener(el, eventName, handler);

The proposed implementation passes a new function to attachEvent instead of the given handler. This new function has no chance to be removed with the corresponding detachEvent.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.