class Event
{
events = {}
on(event, callback){
if(!(event in this.events)){
this.events[event] = [];
}
this.events[event].push(callback);
}
emit(event, ...args){
if(event in this.events){
this.events[event].forEach(callback => callback(...args));
}
}
}
class Cselect extends Event
{
justDoSomething(){
this.emit('tick', 1, 2, 3);
}
}
var select = new Cselect;
select.on('tick', (a, b, c) => {
console.log(a, b, c);
});
select.justDoSomething();
var remote = {
"url": "/matched-cities?q=%QUERY&p=",
"prepare": function(query, settings) {
console.log(remote.wildcard);
},
"wildcard": "%QUERY"
}
var current_city_data_1 = new Bloodhound({
"datumTokenizer": Bloodhound.tokenizers.obj.whitespace('value'),
"queryTokenizer": Bloodhound.tokenizers.whitespace,
"remote":remote
});
!!my.var
просто думал будет более "логично/хороший тон"
if(true == my.var){ ... }
, главное - чтобы ваш код был однотонным и подобные проверки в нем были в одном стиле.if("var" in my && my.var){ ... }
) запись по ряду, не относящихся к вопросу, причин.var my = {
var : '123'
}
var
), то заключайте их в кавычки. Иначе это может привести к ошибкам в некоторых браузерах (к примеру, в IE8).//Bad
var my = {
var : 1,
new : 2
}
//Good
var my = {
"var" : 1,
"new" : 2
}
jQuery.fn.attr
служит для работы с атрибутами DOM-элемента.jQuery.fn.data
тут даже не рядом. Он позволяет сохранить какие-то данные в памяти jQuery, привязав их к конкретной js-сущности (DOM-элементу/другому объекту). А то, что jQuery для хранения значений простых типов по возможности использует data-атрибуты - это уже другая история. Иными словами - данный метод не предназначен для работы с атрибутами.Важная особенность. В момент первого обращения к элементу, все атрибуты data-* будут считаны в память jQuery и доступны через метод jQuery.fn.data, но если добавить еще один атрибут (data-second-attr) то он не будет доступен через данный метод.
<div attr="first" data-name1="second"></div>
//Все доступно сразу
$('div').attr('attr'); // 'first'
$('div').attr('data-name1'); // 'second'
$('div').data('name1'); // 'second'
//Если добавить атрибут методом jQuery.fn.attr (изменение DOM)
$('div').attr('data-name2', 'third');
//то
$('div').attr('data-name2'); // 'third'
$('div').data('name2'); // undefined
//Если 'добавить' атрибут методом jQuery.fn.data (нет изменений DOM)
$('div').data('name3', 'four');
//то
$('div').attr('data-name3'); // undefined
$('div').data('name3'); // 'four'
function createFileTail(string $path){
$server = $_SERVER['DOCUMENT_ROOT'];
$targetFilePath = ($server . $path);
$targetFileTime = filemtime($targetFilePath);
$saveFilePath = ($server . "tailHistory.json");
$saveFileTime = 0;
$history = json_decode(
file_get_contents($saveFilePath), true
);
if(!array_key_exists($path, $history) || $history[$path] < $targetFileTime){
$saveFileTime = $targetFileTime;
$history[$path] = $saveFileTime;
file_put_contents(
$saveFilePath, json_encode($history)
);
}else{
$saveFileTime = $history[$path];
}
return $saveFileTime;
}
src="/client.js?<?=createFileTail('client.js')?>"
var getToken = (function (Win, tokenWindow){
/**
* (Win, tokenWindow)
*
* @param {Window} Win
* @param {Null} tokenWindow
*
* @return {Function} getToken
*/
//ID приложения
var OPTION_APP_ID = 1234567;
//Ссылка для перенаправления (должна быть указана в настройках приложения)
var OPTION_APP_REDIRECT = "http://mysite.ru/vkAuth.php?action=get_token";
//Запрашиваемые права
var OPTION_APP_SCOPE = ["wall", "photos", "offline"];
function http_build_query(obj){
/**
* http_build_query(obj)
*
* @param {Object} obj
*
* @return {String}
*/
var k, res = "";
for(k in obj){
res += ("&" + k + "=" + Win.encodeURIComponent(obj[k]));
}
return res.slice(1);
}
function openTokenWindow(app, redirect, scope){
/**
* openTokenWindow(app, redirect, scope)
*
* @param {Number|String} app
* @param {String} redirect
* @param {Array} scope
*
* @return {Window}
*/
return Win.open("https://oauth.vk.com/authorize?" + http_build_query(
{
"client_id" : app,
"scope" : scope.join(","),
"redirect_uri" : redirect,
"display" : "wap",
"response_type" : "token"
}),
"Авторизация",
(
"menubar=yes," +
"status=yes," +
"toolbar=yes," +
"location=no," +
"resizable=yes," +
"scrollbars=yes," +
"left=50," +
"top=50," +
"width=500," +
"height=500"
)
);
}
return function getToken(callbackSuccess, callbackError){
/**
* getToken(callbackSuccess, callbackError)
*
* @param {Function} callbackSuccess
* @param {Function} callbackError
*
* @return {Undefined}
*/
if(tokenWindow && !tokenWindow.closed){
return alert("Уже открыто окно авторизации"), undefined;
}
tokenWindow = openTokenWindow(OPTION_APP_ID, OPTION_APP_REDIRECT, OPTION_APP_SCOPE);
Win.addEventListener("message", function x(e){
var message = e.data, source = e.source;
if(source === tokenWindow){
tokenWindow = tokenWindow.close(), null;
Win.removeEventListener("message", x);
message = JSON.parse(message);
message.errno ? callbackSuccess(message.token) : callbackError();
}
});
}
})(window, null);
getToken(
function(x){
//Функция, которая будет вызвана при успешной авторизации
alert("Токен:" + x);
},
function(){
//Функция, которая будет вызвана при ошибке
alert("Ошибка");
}
);
redirectURI#access_token={token}&....
, где наше искомое значение - это {token}
!function(hash, win, reg){
/**
* (hash, win, reg)
*
* @param {String} hash
* @param {*} win
* @param {RegExp} reg
*
* @return {Undefined}
*/
//На самом деле, достаточно просто уведомить opener о том, что авторизация успешна.
//А сам токен выдирать из tokenWindow.location.hash
//Но зачем...
var data = reg.exec(hash), token = data && data[1];
win && win.postMessage(
JSON.stringify(
{
errno : data,
token : token
}
)
);
//need targetOrigin condition?
}(location.hash, opener, /access_token=([^&]+)/);