最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

微信小程序后端(java)開發(fā)流程的詳細(xì)步驟

 更新時間:2019年11月13日 11:26:21   作者:CoderZS  
這篇文章主要介紹了微信小程序后端開發(fā)流程的詳細(xì)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

微信小程序后端開發(fā)流程根據(jù)官網(wǎng)總結(jié)為兩個步驟

1、前端調(diào)用 wx.login 返回了code,然后調(diào)用wx.getUserInfo獲取到用戶的昵稱 頭像

 2、服務(wù)端根據(jù)code去微信獲取openid, 接口地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html%EF%BC%9B%E5%90%8C%E6%97%B6%EF%BC%8C%E6%9B%B4%E6%96%B0%E7%94%A8%E6%88%B7%E6%98%B5%E7%A7%B0%E5%A4%B4%E5%83%8F%E7%AD%89%E8%B5%84%E6%96%99

微信小程序后端接口開發(fā)

controller層

public class OauthController {

  @Autowired
  private WeChatService weChatService;

  /**
   * 微信授權(quán)用js_code換取openId
   * @param code
   * @return
   */
  @GetMapping("/code2Session")
  public BaseResponse code2Session(String code) {
    log.info("code2Session,code={}", code);
    if (StringUtil.isEmpty(code)) {
      return BaseResponse.buildFail("參數(shù)異常");
    }
    Code2SessionResponse res = weChatService.code2Session(code);
    log.info("code2Session,res={}", res);
    if (!res.isSuccess()) {
      return BaseResponse.buildFail(res.getErrCode(), res.getErrMsg());
    }
    return BaseResponse.buildSuccess(res);
  }


 /**
   * 解密獲取手機(jī)號
   * @param request
   * @param response
   * @param param
   * @return
   */
  public BaseResponse decryptGetPhone(HttpServletRequest request, HttpServletResponse response,
                  @RequestBody OauthParam param) {
  
      if (!StringUtil.isEmpty(param.getOpenId())) {//微信授權(quán)登錄
        String sessionKey = weChatService.getSessionKey(param.getOpenId());
        if (StringUtil.isEmpty(sessionKey)) {
          return BaseResponse.buildFail("會話不存在");
        }
        Sha1Utils sha = new Sha1Utils();
        // 獲取用戶信息
        log.debug("微信登陸 sessionKey = {}", sessionKey);
        String userInfoStr = sha.decryptWXAppletInfo(sessionKey, param.getEncryptedData(), param.getIv());
        if (StringUtil.isEmpty(userInfoStr)) {
          return BaseResponse.buildFail("無法獲取用戶信息");
        }
        JSONObject json = JSONObject.parseObject(userInfoStr);
        //綁定微信的手機(jī)號
        String tel = json.getString("purePhoneNumber");
        Assert.isTrue(!StringUtils.isEmpty(tel), "無法獲取用戶手機(jī)號");
        BaseResponse baseResponse=new BaseResponse();
        baseResponse.setResultInfo(tel);
        baseResponse.setState(0);
        return baseResponse;
      }

  }
}

接口

public interface WeChatService {


  /**
   * 用code換取openid
   *
   * @param code
   * @return
   */
  Code2SessionResponse code2Session(String code);


  /**
   * 獲取憑證
   *
   * @return
   */
  String getAccessToken();


  /**
   * 獲取憑證
   *
   * @param isForce
   * @return
   */
  String getAccessToken(boolean isForce);


  String getSessionKey(String openId);

}

實現(xiàn)類

public class WeChatServiceImpl implements WeChatService {

  //獲取配置文件數(shù)據(jù)
  @Value("${wechat.miniprogram.id}")
  private String appId;

  @Value("${wechat.miniprogram.secret}")
  private String appSecret;

  @Reference
  private SysUserService sysUserService;


  @Override
  public Code2SessionResponse code2Session(String code) {
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_CODE2SESSION, appId, appSecret, code));
    log.info("rawResponse====={}", rawResponse);
    Code2SessionResponse response = JSON.parseObject(rawResponse, Code2SessionResponse.class);
    if (response.isSuccess()) {
      cacheSessionKey(response);
    }
    return response;
  }

  private void cacheSessionKey(Code2SessionResponse response) {
    RedisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(response.getOpenId());
    redisCache.setCache(key, 2147483647, response.getSessionKey());
  }

  @Override
  public String getAccessToken() {
    return getAccessToken(false);
  }

  @Override
  public String getAccessToken(boolean isForce) {
    RedisCache redisCache = RedisCache.getInstance();
    String accessToken = null;
    if (!isForce) {
      accessToken = redisCache.getCache(RedisCacheKeys.getWxAccessTokenKey(appId));
    }
    if (StringUtil.isNotEmpty(accessToken)) {
      return accessToken;
    }
    String rawResponse = HttpClientUtil
        .get(String.format(WechatConstant.URL_GET_ACCESS_TOKEN, appId, appSecret));
    AccessTokenResponse response = JSON.parseObject(rawResponse, AccessTokenResponse.class);
    log.info("getAccessToken:response={}", response);
    if (response.isSuccess()) {
      redisCache.setCache(RedisCacheKeys.getWxAccessTokenKey(appId), 7000, response.getAcessToken());
      return response.getAcessToken();
    }
    return null;
  }


  @Override
  public String getSessionKey(String openId) {
    RedisCache redisCache = RedisCache.getInstance();
    String key = RedisCacheKeys.getWxSessionKeyKey(openId);
    String sessionKey = redisCache.getCache(key);
    return sessionKey;
  }
}

用到的解密工具類

public class Sha1Utils {
  public static String decryptWXAppletInfo(String sessionKey, String encryptedData, String iv) {
    String result = null;
    try {
      byte[] encrypData = Base64.decodeBase64(encryptedData);
      byte[] ivData = Base64.decodeBase64(iv);
      byte[] sessionKeyB = Base64.decodeBase64(sessionKey);

      AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
      SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, "AES");
      cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
      byte[] doFinal = cipher.doFinal(encrypData);
      result = new String(doFinal);
      return result;
    } catch (Exception e) {
      //e.printStackTrace();
      log.error("decryptWXAppletInfo error",e);
    }
    return null;
  }

}

網(wǎng)絡(luò)請求工具類

public class HttpClientUtil {

  // utf-8字符編碼
  public static final String            CHARSET_UTF_8     = "utf-8";

  // HTTP內(nèi)容類型。
  public static final String            CONTENT_TYPE_TEXT_HTML = "text/xml";

  // HTTP內(nèi)容類型。相當(dāng)于form表單的形式,提交數(shù)據(jù)
  public static final String            CONTENT_TYPE_FORM_URL = "application/x-www-form-urlencoded";

  // HTTP內(nèi)容類型。相當(dāng)于form表單的形式,提交數(shù)據(jù)
  public static final String            CONTENT_TYPE_JSON_URL = "application/json;charset=utf-8";

  // 連接管理器
  private static PoolingHttpClientConnectionManager pool;

  // 請求配置
  private static volatile RequestConfig requestConfig;

  private static CloseableHttpClient getNewHttpClient() {

    CloseableHttpClient httpClient = HttpClients.custom()
      // 設(shè)置連接池管理
      .setConnectionManager(pool)
      // 設(shè)置請求配置
      .setDefaultRequestConfig(getRequestConfig())
      // 設(shè)置重試次數(shù)
      .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();

    return httpClient;
  }

  /**
   * 發(fā)送 post請求
   *
   * @param httpUrl
   *      地址
   */
  public static String post(String httpUrl) {
    // 創(chuàng)建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return request(httpPost);
  }

  public static byte[] postRaw(String httpUrl) {
    // 創(chuàng)建httpPost
    HttpPost httpPost = new HttpPost(httpUrl);
    return requestRaw(httpPost);
  }

  /**
   * 發(fā)送 get請求
   *
   * @param httpUrl
   */
  public static String get(String httpUrl) {
    // 創(chuàng)建get請求
    HttpGet httpGet = new HttpGet(httpUrl);
    return request(httpGet);
  }

  /**
   * 發(fā)送 post請求(帶文件)
   *
   * @param httpUrl
   *      地址
   * @param maps
   *      參數(shù)
   * @param fileLists
   *      附件
   */
  public static String post(String httpUrl, Map<String, String> maps, List<File> fileLists,
               String fileName) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
    if (maps != null) {
      for (String key : maps.keySet()) {
        meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
      }
    }
    if (fileLists != null) {
      for (File file : fileLists) {
        FileBody fileBody = new FileBody(file);
        meBuilder.addPart(fileName, fileBody);
      }
    }
    HttpEntity reqEntity = meBuilder.build();
    httpPost.setEntity(reqEntity);
    return request(httpPost);
  }

  public static String post(String httpUrl, Map<String, String> maps, List<File> fileLists) {
    return post(httpUrl, maps, fileLists, "file");
  }

  public static String post(String httpUrl, List<File> fileLists) {
    return post(httpUrl, Collections.emptyMap(), fileLists, "file");
  }

  /**
   * 發(fā)送 post請求
   *
   * @param httpUrl
   *      地址
   * @param params
   *      參數(shù)(格式:key1=value1&key2=value2)
   *
   */
  public static String post(String httpUrl, String params) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    try {
      // 設(shè)置參數(shù)
      if (params != null && params.trim().length() > 0) {
        StringEntity stringEntity = new StringEntity(params, "UTF-8");
        stringEntity.setContentType(CONTENT_TYPE_FORM_URL);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return request(httpPost);
  }

  /**
   * 發(fā)送 post請求
   *
   * @param maps
   *      參數(shù)
   */
  public static String post(String httpUrl, Map<String, String> maps) {
    String param = convertStringParamter(maps);
    return post(httpUrl, param);
  }



  /**
   * 發(fā)送 post請求 發(fā)送json數(shù)據(jù)
   *
   * @param httpUrl
   *      地址
   * @param content
   *
   *
   */
  public static String post(String httpUrl, String content, String contentType) {
    //    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    //    try {
    //      // 設(shè)置參數(shù)
    //      if (StringUtils.isNotEmpty(content)) {
    //        StringEntity stringEntity = new StringEntity(content, "UTF-8");
    //        stringEntity.setContentType(contentType);
    //        httpPost.setEntity(stringEntity);
    //      }
    //    } catch (Exception e) {
    //      e.printStackTrace();
    //    }
    //    return request(httpPost);
    return new String(postRaw(httpUrl, content, contentType), StandardCharsets.UTF_8);
  }

  public static byte[] postRaw(String httpUrl, String content, String contentType) {
    HttpPost httpPost = new HttpPost(httpUrl);// 創(chuàng)建httpPost
    try {
      // 設(shè)置參數(shù)
      if (StringUtils.isNotEmpty(content)) {
        StringEntity stringEntity = new StringEntity(content, "UTF-8");
        stringEntity.setContentType(contentType);
        httpPost.setEntity(stringEntity);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return requestRaw(httpPost);
  }

  /**
   * 發(fā)送 post請求 發(fā)送json數(shù)據(jù)
   *
   * @param httpUrl
   *      地址
   * @param paramsJson
   *      參數(shù)(格式 json)
   *
   */
  public static String postJson(String httpUrl, String paramsJson) {
    return post(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  public static byte[] postJsonRaw(String httpUrl, String paramsJson) {
    return postRaw(httpUrl, paramsJson, CONTENT_TYPE_JSON_URL);
  }

  /**
   * 發(fā)送 post請求 發(fā)送xml數(shù)據(jù)
   *
   * @param url  地址
   * @param paramsXml 參數(shù)(格式 Xml)
   *
   */
  public static String postXml(String url, String paramsXml) {
    return post(url, paramsXml, CONTENT_TYPE_TEXT_HTML);
  }

  /**
   * 將map集合的鍵值對轉(zhuǎn)化成:key1=value1&key2=value2 的形式
   *
   * @param parameterMap
   *      需要轉(zhuǎn)化的鍵值對集合
   * @return 字符串
   */
  public static String convertStringParamter(Map parameterMap) {
    StringBuilder parameterBuffer = new StringBuilder();
    if (parameterMap != null) {
      Iterator iterator = parameterMap.keySet().iterator();
      String key = null;
      String value = null;
      while (iterator.hasNext()) {
        key = (String) iterator.next();
        if (parameterMap.get(key) != null) {
          value = (String) parameterMap.get(key);
        } else {
          value = "";
        }
        parameterBuffer.append(key).append("=").append(value);
        if (iterator.hasNext()) {
          parameterBuffer.append("&");
        }
      }
    }
    return parameterBuffer.toString();
  }

  /**
   * 發(fā)送請求
   *
   * @param request
   * @return
   */
  public static byte[] requestRaw(HttpRequestBase request) {

    CloseableHttpClient httpClient;
    CloseableHttpResponse response = null;
    // 響應(yīng)內(nèi)容
    //    String responseContent = null;
    byte[] rawResponse = null;
    try {
      // 創(chuàng)建默認(rèn)的httpClient實例.
      httpClient = getNewHttpClient();
      // 配置請求信息
      request.setConfig(requestConfig);
      // 執(zhí)行請求
      response = httpClient.execute(request);
      // 得到響應(yīng)實例
      HttpEntity entity = response.getEntity();

      // 可以獲得響應(yīng)頭
      // Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE);
      // for (Header header : headers) {
      // System.out.println(header.getName());
      // }

      // 得到響應(yīng)類型
      // System.out.println(ContentType.getOrDefault(response.getEntity()).getMimeType());

      // 判斷響應(yīng)狀態(tài)
      if (response.getStatusLine().getStatusCode() >= 300) {
        throw new Exception("HTTP Request is not success, Response code is "
                  + response.getStatusLine().getStatusCode());
      }

      if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
        rawResponse = EntityUtils.toByteArray(entity);
        //        responseContent = EntityUtils.toString(entity, CHARSET_UTF_8);
        EntityUtils.consume(entity);
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        // 釋放資源
        if (response != null) {
          response.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return rawResponse;
  }

  private static String request(HttpRequestBase req) {
    return new String(requestRaw(req), StandardCharsets.UTF_8);
  }

  private static RequestConfig getRequestConfig() {

    if (requestConfig == null) {
      synchronized (HttpClientUtil.class) {
        if (requestConfig == null) {
          try {
            //System.out.println("初始化HttpClientTest~~~開始");
            SSLContextBuilder builder = new SSLContextBuilder();
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
              builder.build());
            // 配置同時支持 HTTP 和 HTPPS
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
              .<ConnectionSocketFactory> create()
              .register("http", PlainConnectionSocketFactory.getSocketFactory())
              .register("https", sslsf).build();
            // 初始化連接管理器
            pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            // 將最大連接數(shù)增加到200,實際項目最好從配置文件中讀取這個值
            pool.setMaxTotal(200);
            // 設(shè)置最大路由
            pool.setDefaultMaxPerRoute(2);
            // 根據(jù)默認(rèn)超時限制初始化requestConfig
            int socketTimeout = 10000;
            int connectTimeout = 10000;
            int connectionRequestTimeout = 10000;
            requestConfig = RequestConfig.custom()
              .setConnectionRequestTimeout(connectionRequestTimeout)
              .setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout)
              .build();

          } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
          } catch (KeyStoreException e) {
            e.printStackTrace();
          } catch (KeyManagementException e) {
            e.printStackTrace();
          }

          // 設(shè)置請求超時時間
          requestConfig = RequestConfig.custom().setSocketTimeout(50000)
            .setConnectTimeout(50000).setConnectionRequestTimeout(50000).build();
        }
      }
    }
    return requestConfig;
  }
}

常量

public interface WechatConstant {
  Integer OK_STATUS      = 0;
  String URL_CODE2SESSION   = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";


  String URL_GET_ACCESS_TOKEN   = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";


  String URL_GET_IMAGE = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
  
  
  /**
   * 給公眾號發(fā)送信息。參考https://mp.weixin.qq.com/advanced/tmplmsg?action=faq&token=708366329&lang=zh_CN
   */
  String URL_SEND_TO_CHANNEL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
  String URL_SEND_MESSAGE   = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s";
  
  /**
   * 發(fā)送模板消息。參考https://developers.weixin.qq.com/miniprogram/dev/api-backend/sendMiniTemplateMessage.html
   */
  String URL_SEND_TEMPLATE_MESSAGE = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=%s";

  String URL_QR_CODE_UNLIMTED = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
  
  String URL_QR_CODE = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s";

  /**
   * 獲取標(biāo)簽下粉絲列表
   */
  String URL_ALL_FANS_OPENID = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=%s";
  /**
   * 獲取公眾號已創(chuàng)建的標(biāo)簽
   */
  String URL_ALL_TAGS = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=%s";

}

使用到的實體類

public class Code2SessionResponse implements Serializable {
  public static Integer RESPONSE_OK = 0;

  @JSONField(name = "openid")
  private String    openId;
  @JSONField(name = "session_key")
  private String    sessionKey;
  @JSONField(name = "unionid")
  private String    unionId;
  @JSONField(name = "errcode")
  private Integer   errCode;
  @JSONField(name = "errmsg")
  private String   errMsg;



  public boolean isSuccess() {
    return this.errCode == null || RESPONSE_OK.equals(this.errCode);
  }
}

總結(jié):微信小程序的后端開發(fā)主要就是對用戶進(jìn)行授權(quán) , 1、前端調(diào)用 wx.login 返回了code,然后調(diào)用wx.getUserInfo獲取到用戶的昵稱 頭像 2.首先通過微信授權(quán)用js_code換取openId,來獲取openId,前端傳微信的參數(shù) code字段 3.然后解密獲取手機(jī)號 前端需要傳openId encryptedData iv 等字段來獲取用戶的的授權(quán)手機(jī)號

這些信息都獲取后 接著就是調(diào)用后端的登陸接口,登陸接口如果只有授權(quán)登錄就是我們將接口參數(shù)為下圖最后三個字段為前端必填字段

 

主要步驟是根據(jù)前端的openId獲取sessionKey 然后根據(jù)sessionKey 和其他參數(shù)進(jìn)行解密獲取用戶手機(jī)號

通過解密獲取授權(quán)登錄的手機(jī)號,然后根據(jù)自己的業(yè)務(wù)邏輯處理即可,這樣我們就可以根據(jù)授權(quán)的手機(jī)號進(jìn)行授權(quán)登錄

相關(guān)文章

  • 用JS操作FRAME中的IFRAME及其內(nèi)容的實現(xiàn)代碼

    用JS操作FRAME中的IFRAME及其內(nèi)容的實現(xiàn)代碼

    一直都需要這樣的東西,發(fā)現(xiàn)了這個好東西,一定要研究下
    2008-07-07
  • 原生js jquery ajax請求以及jsonp的調(diào)用方法

    原生js jquery ajax請求以及jsonp的調(diào)用方法

    下面小編就為大家?guī)硪黄鷍s jquery ajax請求以及jsonp的調(diào)用方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • JavaScript解析任意形式的json樹型結(jié)構(gòu)展示

    JavaScript解析任意形式的json樹型結(jié)構(gòu)展示

    這篇文章主要介紹了JavaScript解析任意形式的json樹型結(jié)構(gòu)展示的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • JS實現(xiàn)的幾個常用算法

    JS實現(xiàn)的幾個常用算法

    本文給大家分享日常中比較熟悉的常用的幾個算法用JS的實現(xiàn),非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-11-11
  • 通過循環(huán)優(yōu)化 JavaScript 程序

    通過循環(huán)優(yōu)化 JavaScript 程序

    這篇文章主要介紹了通過循環(huán)優(yōu)化 JavaScript 程序,對于提高 JavaScript 程序的性能這個問題,最簡單同時也是很容易被忽視的方法就是學(xué)習(xí)如何正確編寫高性能循環(huán)語句。下面我們來學(xué)習(xí)一下吧
    2019-06-06
  • Bootstrap fileinput文件上傳組件使用詳解

    Bootstrap fileinput文件上傳組件使用詳解

    這篇文章主要為大家詳細(xì)介紹了Bootstrap fileinput文件上傳組件的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 小程序錄音功能實現(xiàn)

    小程序錄音功能實現(xiàn)

    這篇文章主要介紹了小程序錄音功能實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • js 自帶的sort() 方法全面了解

    js 自帶的sort() 方法全面了解

    下面小編就為大家?guī)硪黄猨s 自帶的sort() 方法全面了解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 微信小程序音樂播放器開發(fā)

    微信小程序音樂播放器開發(fā)

    這篇文章主要為大家詳細(xì)介紹了微信小程序音樂播放器開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 用js實現(xiàn)層隨著內(nèi)容大小動態(tài)漸變改變 推薦

    用js實現(xiàn)層隨著內(nèi)容大小動態(tài)漸變改變 推薦

    以前做谷歌的小工具時,api里提供了一個很有用的函數(shù),那就是在程序運(yùn)行時可以使層動態(tài)隨內(nèi)容大小而變化,而且是平滑變換,在一些jquery的lightbox里也普遍有這種效果,看起來很酷的樣子。
    2009-12-12

最新評論

琼中| 民乐县| 大厂| 保康县| 梅州市| 香港| 海阳市| 南昌县| 沧州市| 平邑县| 漳平市| 赣州市| 常山县| 竹北市| 天水市| 陵川县| 稻城县| 涟水县| 达尔| 遵义县| 东宁县| 新营市| 诏安县| 永登县| 陆河县| 固原市| 彰武县| 双峰县| 贵德县| 曲周县| 大宁县| 抚宁县| 四子王旗| 和平县| 达州市| 论坛| 河间市| 门头沟区| 仙居县| 监利县| 安溪县|